File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_TOKENIZE_HPP
0015 #define RANGES_V3_VIEW_TOKENIZE_HPP
0016
0017 #include <initializer_list>
0018 #include <regex>
0019 #include <type_traits>
0020 #include <utility>
0021 #include <vector>
0022
0023 #include <range/v3/range_fwd.hpp>
0024
0025 #include <range/v3/functional/bind_back.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/range/concepts.hpp>
0028 #include <range/v3/utility/static_const.hpp>
0029 #include <range/v3/view/all.hpp>
0030 #include <range/v3/view/interface.hpp>
0031 #include <range/v3/view/view.hpp>
0032
0033 #include <range/v3/detail/prologue.hpp>
0034
0035 namespace ranges
0036 {
0037
0038
0039 template<typename Rng, typename Regex, typename SubMatchRange>
0040 struct tokenize_view
0041 : view_interface<tokenize_view<Rng, Regex, SubMatchRange>,
0042 is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0043 {
0044 private:
0045 CPP_assert(bidirectional_range<Rng> && view_<Rng> && common_range<Rng>);
0046 CPP_assert(semiregular<Regex>);
0047 CPP_assert(semiregular<SubMatchRange>);
0048
0049 Rng rng_;
0050 Regex rex_;
0051 SubMatchRange subs_;
0052 std::regex_constants::match_flag_type flags_;
0053 template<bool Const>
0054 using iterator_t =
0055 std::regex_token_iterator<iterator_t<meta::const_if_c<Const, Rng>>>;
0056
0057 public:
0058 tokenize_view() = default;
0059 tokenize_view(Rng rng, Regex rex, SubMatchRange subs,
0060 std::regex_constants::match_flag_type flags)
0061 : rng_(std::move(rng))
0062 , rex_(std::move(rex))
0063 , subs_(std::move(subs))
0064 , flags_(flags)
0065 {}
0066 iterator_t<simple_view<Rng>()> begin()
0067 {
0068 meta::const_if_c<simple_view<Rng>(), Rng> & rng = rng_;
0069 return {ranges::begin(rng), ranges::end(rng), rex_, subs_, flags_};
0070 }
0071 template(bool Const = true)(
0072 requires range<Rng const>)
0073 iterator_t<Const> begin() const
0074 {
0075 return {ranges::begin(rng_), ranges::end(rng_), rex_, subs_, flags_};
0076 }
0077 iterator_t<simple_view<Rng>()> end()
0078 {
0079 return {};
0080 }
0081 template(bool Const = true)(
0082 requires range<Rng const>)
0083 iterator_t<Const> end() const
0084 {
0085 return {};
0086 }
0087 Rng base() const
0088 {
0089 return rng_;
0090 }
0091 };
0092
0093 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0094 template(typename Rng, typename Regex, typename SubMatchRange)(
0095 requires copy_constructible<Regex> AND copy_constructible<SubMatchRange>)
0096 tokenize_view(Rng &&, Regex, SubMatchRange)
0097 ->tokenize_view<views::all_t<Rng>, Regex, SubMatchRange>;
0098 #endif
0099
0100 namespace views
0101 {
0102 struct tokenize_base_fn
0103 {
0104 template(typename Rng, typename Regex)(
0105 requires bidirectional_range<Rng> AND common_range<Rng> AND
0106 same_as<
0107 range_value_t<Rng>,
0108 typename detail::decay_t<Regex>::value_type>)
0109 tokenize_view<all_t<Rng>, detail::decay_t<Regex>, int>
0110 operator()(Rng && rng,
0111 Regex && rex,
0112 int sub = 0,
0113 std::regex_constants::match_flag_type flags =
0114 std::regex_constants::match_default) const
0115 {
0116 return {all(static_cast<Rng &&>(rng)),
0117 static_cast<Regex &&>(rex),
0118 sub,
0119 flags};
0120 }
0121
0122 template(typename Rng, typename Regex)(
0123 requires bidirectional_range<Rng> AND common_range<Rng> AND
0124 same_as<range_value_t<Rng>,
0125 typename detail::decay_t<Regex>::value_type>)
0126 tokenize_view<all_t<Rng>, detail::decay_t<Regex>, std::vector<int>>
0127 operator()(Rng && rng,
0128 Regex && rex,
0129 std::vector<int> subs,
0130 std::regex_constants::match_flag_type flags =
0131 std::regex_constants::match_default) const
0132 {
0133 return {all(static_cast<Rng &&>(rng)),
0134 static_cast<Regex &&>(rex),
0135 std::move(subs),
0136 flags};
0137 }
0138
0139 template(typename Rng, typename Regex)(
0140 requires bidirectional_range<Rng> AND common_range<Rng> AND
0141 same_as<range_value_t<Rng>,
0142 typename detail::decay_t<Regex>::value_type>)
0143 tokenize_view<all_t<Rng>,
0144 detail::decay_t<Regex>,
0145 std::initializer_list<int>>
0146 operator()(Rng && rng,
0147 Regex && rex,
0148 std::initializer_list<int> subs,
0149 std::regex_constants::match_flag_type flags =
0150 std::regex_constants::match_default) const
0151 {
0152 return {all(static_cast<Rng &&>(rng)),
0153 static_cast<Regex &&>(rex),
0154 std::move(subs),
0155 flags};
0156 }
0157 };
0158
0159 struct tokenize_fn : tokenize_base_fn
0160 {
0161 using tokenize_base_fn::operator();
0162
0163 template<typename Regex>
0164 constexpr auto operator()(Regex && rex,
0165 int sub = 0,
0166 std::regex_constants::match_flag_type flags =
0167 std::regex_constants::match_default) const
0168 {
0169 return make_view_closure(bind_back(
0170 tokenize_base_fn{}, static_cast<Regex &&>(rex), sub, flags));
0171 }
0172
0173 template<typename Regex>
0174 auto operator()(Regex && rex,
0175 std::vector<int> subs,
0176 std::regex_constants::match_flag_type flags =
0177 std::regex_constants::match_default) const
0178 {
0179 return bind_back(tokenize_base_fn{},
0180 static_cast<Regex &&>(rex),
0181 std::move(subs),
0182 flags);
0183 }
0184
0185 template<typename Regex>
0186 constexpr auto operator()(Regex && rex,
0187 std::initializer_list<int> subs,
0188 std::regex_constants::match_flag_type flags =
0189 std::regex_constants::match_default) const
0190 {
0191 return make_view_closure(bind_back(
0192 tokenize_base_fn{}, static_cast<Regex &&>(rex), subs, flags));
0193 }
0194 };
0195
0196
0197
0198 RANGES_INLINE_VARIABLE(tokenize_fn, tokenize)
0199 }
0200
0201 }
0202
0203 #include <range/v3/detail/epilogue.hpp>
0204 #include <range/v3/detail/satisfy_boost_range.hpp>
0205 RANGES_SATISFY_BOOST_RANGE(::ranges::tokenize_view)
0206
0207 #endif