Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:29

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