Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:53:58

0001 //
0002 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_FORMAT_HPP
0011 #define BOOST_URL_FORMAT_HPP
0012 
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/core/detail/string_view.hpp>
0015 #include <boost/url/url.hpp>
0016 #include <boost/url/detail/vformat.hpp>
0017 #include <initializer_list>
0018 
0019 #ifdef BOOST_URL_HAS_CONCEPTS
0020 #include <concepts>
0021 #endif
0022 
0023 namespace boost {
0024 namespace urls {
0025 
0026 /** A temporary reference to a named formatting argument
0027 
0028     This class represents a temporary reference
0029     to a named formatting argument used by the
0030     @ref format function.
0031 
0032     Named arguments should always be created
0033     with the @ref arg function.
0034 
0035     Any type that can be formatted into a URL
0036     with the @ref format function can also be used
0037     in a named argument. All named arguments
0038     are convertible to @ref format_arg and
0039     can be used in the @ref format function.
0040 
0041     @see
0042         @ref arg,
0043         @ref format,
0044         @ref format_to,
0045         @ref format_arg.
0046   */
0047 template <class T>
0048 using named_arg = detail::named_arg<T>;
0049 
0050 /** A temporary reference to a formatting argument
0051 
0052     This class represents a temporary reference
0053     to a formatting argument used by the
0054     @ref format function.
0055 
0056     A @ref format argument should always be
0057     created by passing the argument to be
0058     formatted directly to the @ref format function.
0059 
0060     Any type that can be formatted into a URL
0061     with the @ref format function is convertible
0062     to this type.
0063 
0064     This includes basic types, types convertible
0065     to `core::string_view`, and @ref named_arg.
0066 
0067     @see
0068         @ref format,
0069         @ref format_to,
0070         @ref arg.
0071   */
0072 using format_arg = detail::format_arg;
0073 
0074 /** Format arguments into a URL
0075 
0076     Format arguments according to the format
0077     URL string into a @ref url.
0078 
0079     The rules for a format URL string are the same
0080     as for a `std::format_string`, where replacement
0081     fields are delimited by curly braces.
0082 
0083     The URL components to which replacement fields
0084     belong are identified before replacement is
0085     applied and any invalid characters for that
0086     formatted argument are percent-escaped.
0087 
0088     Hence, the delimiters between URL components,
0089     such as `:`, `//`, `?`, and `#`, should be
0090     included in the URL format string. Likewise,
0091     a format string with a single `"{}"` is
0092     interpreted as a path and any replacement
0093     characters invalid in this component will be
0094     encoded to form a valid URL.
0095 
0096     @par Example
0097     @code
0098     assert(format("{}", "Hello world!").buffer() == "Hello%20world%21");
0099     @endcode
0100 
0101     @par Preconditions
0102     All replacement fields must be valid and the
0103     resulting URL should be valid after arguments
0104     are formatted into the URL.
0105 
0106     Because any invalid characters for a URL
0107     component are encoded by this function, only
0108     replacements in the scheme and port components
0109     might be invalid, as these components do not
0110     allow percent-encoding of arbitrary
0111     characters.
0112 
0113     @return A URL holding the formatted result.
0114 
0115     @param fmt The format URL string.
0116     @param args Arguments to be formatted.
0117 
0118     @throws system_error
0119     `fmt` contains an invalid format string and
0120     the result contains an invalid URL after
0121     replacements are applied.
0122 
0123     @par BNF
0124     @code
0125     replacement_field ::=  "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
0126     arg_id            ::=  integer | identifier
0127     integer           ::=  digit+
0128     digit             ::=  "0"..."9"
0129     identifier        ::=  id_start id_continue*
0130     id_start          ::=  "a"..."z" | "A"..."Z" | "_"
0131     id_continue       ::=  id_start | digit
0132     @endcode
0133 
0134     @par Specification
0135     @li <a href="https://fmt.dev/latest/syntax.html"
0136         >Format String Syntax</a>
0137 
0138     @see
0139         @ref format_to,
0140         @ref arg.
0141 */
0142 template <BOOST_URL_CONSTRAINT(std::convertible_to<format_arg>)... Args>
0143 url
0144 format(
0145     core::string_view fmt,
0146     Args&&... args)
0147 {
0148     return detail::vformat(
0149         fmt, detail::make_format_args(
0150             std::forward<Args>(args)...));
0151 }
0152 
0153 /** Format arguments into a URL
0154 
0155     Format arguments according to the format
0156     URL string into a @ref url_base.
0157 
0158     The rules for a format URL string are the same
0159     as for a `std::format_string`, where replacement
0160     fields are delimited by curly braces.
0161 
0162     The URL components to which replacement fields
0163     belong are identified before replacement is
0164     applied and any invalid characters for that
0165     formatted argument are percent-escaped.
0166 
0167     Hence, the delimiters between URL components,
0168     such as `:`, `//`, `?`, and `#`, should be
0169     included in the URL format string. Likewise,
0170     a format string with a single `"{}"` is
0171     interpreted as a path and any replacement
0172     characters invalid in this component will be
0173     encoded to form a valid URL.
0174 
0175     @par Example
0176     @code
0177     static_url<30> u;
0178     format(u, "{}", "Hello world!");
0179     assert(u.buffer() == "Hello%20world%21");
0180     @endcode
0181 
0182     @par Preconditions
0183     All replacement fields must be valid and the
0184     resulting URL should be valid after arguments
0185     are formatted into the URL.
0186 
0187     Because any invalid characters for a URL
0188     component are encoded by this function, only
0189     replacements in the scheme and port components
0190     might be invalid, as these components do not
0191     allow percent-encoding of arbitrary
0192     characters.
0193 
0194     @par Exception Safety
0195     Strong guarantee.
0196 
0197     @param u An object that derives from @ref url_base.
0198     @param fmt The format URL string.
0199     @param args Arguments to be formatted.
0200 
0201     @throws system_error
0202     `fmt` contains an invalid format string and
0203     `u` contains an invalid URL after replacements
0204     are applied.
0205 
0206     @par BNF
0207     @code
0208     replacement_field ::=  "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
0209     arg_id            ::=  integer | identifier
0210     integer           ::=  digit+
0211     digit             ::=  "0"..."9"
0212     identifier        ::=  id_start id_continue*
0213     id_start          ::=  "a"..."z" | "A"..."Z" | "_"
0214     id_continue       ::=  id_start | digit
0215     @endcode
0216 
0217     @par Specification
0218     @li <a href="https://fmt.dev/latest/syntax.html"
0219         >Format String Syntax</a>
0220 
0221     @see
0222         @ref format.
0223 
0224 */
0225 template <BOOST_URL_CONSTRAINT(std::convertible_to<format_arg>)... Args>
0226 void
0227 format_to(
0228     url_base& u,
0229     core::string_view fmt,
0230     Args&&... args)
0231 {
0232     detail::vformat_to(
0233         u, fmt, detail::make_format_args(
0234             std::forward<Args>(args)...));
0235 }
0236 
0237 /** Format arguments into a URL
0238 
0239     Format arguments according to the format
0240     URL string into a @ref url.
0241 
0242     This overload allows type-erased arguments
0243     to be passed as an initializer_list, which
0244     is mostly convenient for named parameters.
0245 
0246     All arguments must be convertible to a
0247     implementation defined type able to store a
0248     type-erased reference to any valid format
0249     argument.
0250 
0251     The rules for a format URL string are the same
0252     as for a `std::format_string`, where replacement
0253     fields are delimited by curly braces.
0254 
0255     The URL components to which replacement fields
0256     belong are identified before replacement is
0257     applied and any invalid characters for that
0258     formatted argument are percent-escaped.
0259 
0260     Hence, the delimiters between URL components,
0261     such as `:`, `//`, `?`, and `#`, should be
0262     included in the URL format string. Likewise,
0263     a format string with a single `"{}"` is
0264     interpreted as a path and any replacement
0265     characters invalid in this component will be
0266     encoded to form a valid URL.
0267 
0268     @par Example
0269     @code
0270     assert(format("user/{id}", {{"id", 1}}).buffer() == "user/1");
0271     @endcode
0272 
0273     @par Preconditions
0274     All replacement fields must be valid and the
0275     resulting URL should be valid after arguments
0276     are formatted into the URL.
0277 
0278     Because any invalid characters for a URL
0279     component are encoded by this function, only
0280     replacements in the scheme and port components
0281     might be invalid, as these components do not
0282     allow percent-encoding of arbitrary
0283     characters.
0284 
0285     @return A URL holding the formatted result.
0286 
0287     @param fmt The format URL string.
0288     @param args Arguments to be formatted.
0289 
0290     @throws system_error
0291     `fmt` contains an invalid format string and
0292     the result contains an invalid URL after
0293     replacements are applied.
0294 
0295     @par BNF
0296     @code
0297     replacement_field ::=  "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
0298     arg_id            ::=  integer | identifier
0299     integer           ::=  digit+
0300     digit             ::=  "0"..."9"
0301     identifier        ::=  id_start id_continue*
0302     id_start          ::=  "a"..."z" | "A"..."Z" | "_"
0303     id_continue       ::=  id_start | digit
0304     @endcode
0305 
0306     @par Specification
0307     @li <a href="https://fmt.dev/latest/syntax.html"
0308         >Format String Syntax</a>
0309 
0310     @see
0311         @ref format_to.
0312 
0313 */
0314 inline
0315 url
0316 format(
0317     core::string_view fmt,
0318     std::initializer_list<format_arg> args)
0319 {
0320     return detail::vformat(
0321         fmt, detail::format_args(
0322             args.begin(), args.end()));
0323 }
0324 
0325 /** Format arguments into a URL
0326 
0327     Format arguments according to the format
0328     URL string into a @ref url_base.
0329 
0330     This overload allows type-erased arguments
0331     to be passed as an initializer_list, which
0332     is mostly convenient for named parameters.
0333 
0334     All arguments must be convertible to a
0335     implementation defined type able to store a
0336     type-erased reference to any valid format
0337     argument.
0338 
0339     The rules for a format URL string are the same
0340     as for a `std::format_string`, where replacement
0341     fields are delimited by curly braces.
0342 
0343     The URL components to which replacement fields
0344     belong are identified before replacement is
0345     applied and any invalid characters for that
0346     formatted argument are percent-escaped.
0347 
0348     Hence, the delimiters between URL components,
0349     such as `:`, `//`, `?`, and `#`, should be
0350     included in the URL format string. Likewise,
0351     a format string with a single `"{}"` is
0352     interpreted as a path and any replacement
0353     characters invalid in this component will be
0354     encoded to form a valid URL.
0355 
0356     @par Example
0357     @code
0358     static_url<30> u;
0359     format_to(u, "user/{id}", {{"id", 1}})
0360     assert(u.buffer() == "user/1");
0361     @endcode
0362 
0363     @par Preconditions
0364     All replacement fields must be valid and the
0365     resulting URL should be valid after arguments
0366     are formatted into the URL.
0367 
0368     Because any invalid characters for a URL
0369     component are encoded by this function, only
0370     replacements in the scheme and port components
0371     might be invalid, as these components do not
0372     allow percent-encoding of arbitrary
0373     characters.
0374 
0375     @par Exception Safety
0376     Strong guarantee.
0377 
0378     @param u An object that derives from @ref url_base.
0379     @param fmt The format URL string.
0380     @param args Arguments to be formatted.
0381 
0382     @throws system_error
0383     `fmt` contains an invalid format string and
0384     `u` contains an invalid URL after replacements
0385     are applied.
0386 
0387     @par BNF
0388     @code
0389     replacement_field ::=  "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
0390     arg_id            ::=  integer | identifier
0391     integer           ::=  digit+
0392     digit             ::=  "0"..."9"
0393     identifier        ::=  id_start id_continue*
0394     id_start          ::=  "a"..."z" | "A"..."Z" | "_"
0395     id_continue       ::=  id_start | digit
0396     @endcode
0397 
0398     @par Specification
0399     @li <a href="https://fmt.dev/latest/syntax.html"
0400         >Format String Syntax</a>
0401 
0402     @see
0403         @ref format.
0404 
0405 */
0406 inline
0407 void
0408 format_to(
0409     url_base& u,
0410     core::string_view fmt,
0411     std::initializer_list<format_arg> args)
0412 {
0413     detail::vformat_to(
0414         u, fmt, detail::format_args(
0415             args.begin(), args.end()));
0416 }
0417 
0418 /** Designate a named argument for a replacement field
0419 
0420     Construct a named argument for a format URL
0421     string that contains named replacement fields.
0422 
0423     The function parameters should be convertible
0424     to an implementation defined type able to
0425     store the name and a reference to any type
0426     potentially used as a format argument.
0427 
0428     @par Example
0429     The function should be used to designate a named
0430     argument for a replacement field in a format
0431     URL string.
0432     @code
0433     assert(format("user/{id}", arg("id", 1)).buffer() == "user/1");
0434     @endcode
0435 
0436     @return A temporary object with reference
0437     semantics for a named argument
0438 
0439     @param name The format argument name
0440     @param arg The format argument value
0441 
0442     @see
0443         @ref format,
0444         @ref format_to.
0445 
0446 */
0447 template <class T>
0448 named_arg<T>
0449 arg(core::string_view name, T const& arg)
0450 {
0451     return {name, arg};
0452 }
0453 
0454 } // url
0455 } // boost
0456 
0457 #endif