![]() |
|
|||
File indexing completed on 2025-09-17 08:39:23
0001 // 0002 // Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot 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 0008 #ifndef BOOST_MYSQL_SEQUENCE_HPP 0009 #define BOOST_MYSQL_SEQUENCE_HPP 0010 0011 #include <boost/mysql/detail/sequence.hpp> 0012 0013 #ifdef BOOST_MYSQL_HAS_CONCEPTS 0014 #include <concepts> 0015 #endif 0016 0017 namespace boost { 0018 namespace mysql { 0019 0020 /** 0021 * \brief The return type of \ref sequence. 0022 * \details 0023 * Contains a range, a formatter function, and a glue string. 0024 * This type satisfies the `Formattable` concept. 0025 * 0026 * When formatted, \ref format_function is invoked for each element 0027 * in \ref range. The string \ref glue is output raw (as per \ref format_context_base::append_raw) 0028 * between consecutive invocations of the formatter function, generating an effect 0029 * similar to `std::ranges::views::join`. 0030 * 0031 * Don't instantiate this struct directly - use \ref sequence, instead. 0032 * 0033 * \par Type requirements 0034 * 0035 * - Expressions `std::begin(range)` and `std::end(range)` should return an input iterator/sentinel 0036 * pair that can be compared for (in)equality. 0037 * - The expression `static_cast<const FormatFn&>(fn)(* std::begin(range), ctx)` 0038 * should be well formed, with `ctx` begin a `format_context_base&`. 0039 */ 0040 template <class Range, class FormatFn> 0041 #if defined(BOOST_MYSQL_HAS_CONCEPTS) 0042 requires detail::format_fn_for_range<FormatFn, Range> 0043 #endif 0044 struct format_sequence 0045 { 0046 /// The range to format. 0047 Range range; 0048 0049 /// The format function to apply to each element in the range. 0050 FormatFn format_function; 0051 0052 /// The string to output between range elements. 0053 constant_string_view glue; 0054 }; 0055 0056 /** 0057 * \brief The type of range produced by \ref sequence. 0058 * \details 0059 * This type trait can be used to obtain the range type produced 0060 * by calling \ref sequence. This type is used as the `Range` template 0061 * parameter in \ref format_sequence. 0062 * 0063 * By default, \ref sequence copies its input range, unless 0064 * using `std::ref`. C arrays are copied into `std::array` objects. 0065 * This type trait accounts these transformations. 0066 * 0067 * Formally, given the input range type `T` (which can be a reference with cv-qualifiers): 0068 * 0069 * - If `T` is a C array or a reference to one (as per `std::is_array`), 0070 * and the array elements' type is `U`, yields `std::array<std::remove_cv_t<U>, N>`. 0071 * - If `T` is a `std::reference_wrapper<U>` object, or a reference to one, 0072 * yields `U&`. 0073 * - Otherwise, yields `std::remove_cvref_t<T>`. 0074 * 0075 * Examples: 0076 * 0077 * - `sequence_range_t<const std::vector<int>&>` is `std::vector<int>`. 0078 * - `sequence_range_t<std::reference_wrapper<std::vector<int>>>` is `std::vector<int>&`. 0079 * - `sequence_range_t<std::reference_wrapper<const std::vector<int>>>` is `const std::vector<int>&`. 0080 * - `sequence_range_t<int(&)[4]>` is `std::array<int, 4>`. 0081 */ 0082 template <class T> 0083 using sequence_range_t = 0084 #ifdef BOOST_MYSQL_DOXYGEN 0085 __see_below__ 0086 #else 0087 typename detail::sequence_range_type<T>::type; 0088 #endif 0089 ; 0090 0091 /** 0092 * \brief Creates an object that, when formatted, applies a per-element function to a range. 0093 * \details 0094 * Objects returned by this function satisfy `Formattable`. 0095 * Formatting such objects invokes `fn` for each element 0096 * in `range`, outputting `glue` between invocations. 0097 * This generates an effect similar to `std::ranges::views::join`. 0098 * 0099 * By default, this function creates an owning object by decay-copying `range` into it. 0100 * C arrays are copied into `std::array` objects. This behavior can be disabled 0101 * by passing `std::reference_wrapper` objects, which are converted to references 0102 * (as `std::make_tuple` does). The \ref sequence_range_t 0103 * type trait accounts for these transformations. 0104 * 0105 * Formally: 0106 * 0107 * - If `Range` is a (possibly cv-qualified) C array reference (as per `std::is_array<Range>`), 0108 * and the array has `N` elements of type `U`, the output range type is 0109 * `std::array<std::remove_cv< U >, N>`, and the range is created as if `std::to_array` was called. 0110 * - If `Range` is a `std::reference_wrapper< U >` object, or a reference to one, 0111 * the output range type is `U&`. This effectively disables copying the input range. 0112 * The resulting object will be a view type, and the caller is responsible for lifetime management. 0113 * - Otherwise, the output range type is `std::remove_cvref_t<Range>`, and it will be 0114 * created by forwarding the passed `range`. 0115 * 0116 * `FormatFn` is always decay-copied into the resulting object. 0117 * 0118 * The glue string is always stored as a view, as it should usually point to a compile-time constant. 0119 * 0120 * \par Type requirements 0121 * 0122 * The resulting range and format function should be compatible, and any required 0123 * copy/move operations should be well defined. Formally: 0124 * 0125 * - `std::decay_t<FormatFn>` should be a formatter function compatible with 0126 * the elements of the output range. See \ref format_sequence for the formal requirements. 0127 * - If `Range` is a `std::reference_wrapper< U >`, or a reference to one, 0128 * no further requirements are placed on `U`. 0129 * - If `Range` is a lvalue reference to a C array, its elements should be copy-constructible 0130 * (as per `std::to_array` requirements). 0131 * - If `Range` is a rvalue reference to a C array, its elements should be move-constructible 0132 * (as per `std::to_array` requirements). 0133 * - Performing a decay-copy of `FormatFn` should be well defined. 0134 * 0135 * \par Exception safety 0136 * Basic guarantee. Propagates any exception thrown when constructing the output 0137 * range and format function. 0138 */ 0139 template <class Range, class FormatFn> 0140 #if defined(BOOST_MYSQL_HAS_CONCEPTS) 0141 requires std::constructible_from<typename std::decay<FormatFn>::type, FormatFn&&> 0142 #endif 0143 format_sequence<sequence_range_t<Range>, typename std::decay<FormatFn>::type> sequence( 0144 Range&& range, 0145 FormatFn&& fn, 0146 constant_string_view glue = ", " 0147 ) 0148 0149 { 0150 return {detail::cast_range(std::forward<Range>(range)), std::forward<FormatFn>(fn), glue}; 0151 } 0152 0153 template <class Range, class FormatFn> 0154 struct formatter<format_sequence<Range, FormatFn>> 0155 { 0156 const char* parse(const char* begin, const char*) { return begin; } 0157 0158 void format(format_sequence<Range, FormatFn>& value, format_context_base& ctx) const 0159 { 0160 detail::do_format_sequence(value.range, value.format_function, value.glue, ctx); 0161 } 0162 0163 void format(const format_sequence<Range, FormatFn>& value, format_context_base& ctx) const 0164 { 0165 detail::do_format_sequence(value.range, value.format_function, value.glue, ctx); 0166 } 0167 }; 0168 0169 } // namespace mysql 0170 } // namespace boost 0171 0172 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |