00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_
00030 #define ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_
00031
00032 #include <array>
00033 #include <initializer_list>
00034 #include <iterator>
00035 #include <map>
00036 #include <type_traits>
00037 #include <utility>
00038 #include <vector>
00039
00040 #include "absl/base/macros.h"
00041 #include "absl/base/port.h"
00042 #include "absl/meta/type_traits.h"
00043 #include "absl/strings/string_view.h"
00044
00045 #ifdef _GLIBCXX_DEBUG
00046 #include "absl/strings/internal/stl_type_traits.h"
00047 #endif // _GLIBCXX_DEBUG
00048
00049 namespace absl {
00050 namespace strings_internal {
00051
00052
00053
00054
00055
00056 class ConvertibleToStringView {
00057 public:
00058 ConvertibleToStringView(const char* s)
00059 : value_(s) {}
00060 ConvertibleToStringView(char* s) : value_(s) {}
00061 ConvertibleToStringView(absl::string_view s)
00062 : value_(s) {}
00063 ConvertibleToStringView(const std::string& s)
00064 : value_(s) {}
00065
00066
00067 ConvertibleToStringView(std::string&& s)
00068 : copy_(std::move(s)), value_(copy_) {}
00069
00070 ConvertibleToStringView(const ConvertibleToStringView& other)
00071 : copy_(other.copy_),
00072 value_(other.IsSelfReferential() ? copy_ : other.value_) {}
00073
00074 ConvertibleToStringView(ConvertibleToStringView&& other) {
00075 StealMembers(std::move(other));
00076 }
00077
00078 ConvertibleToStringView& operator=(ConvertibleToStringView other) {
00079 StealMembers(std::move(other));
00080 return *this;
00081 }
00082
00083 absl::string_view value() const { return value_; }
00084
00085 private:
00086
00087 bool IsSelfReferential() const { return value_.data() == copy_.data(); }
00088
00089 void StealMembers(ConvertibleToStringView&& other) {
00090 if (other.IsSelfReferential()) {
00091 copy_ = std::move(other.copy_);
00092 value_ = copy_;
00093 other.value_ = other.copy_;
00094 } else {
00095 value_ = other.value_;
00096 }
00097 }
00098
00099
00100
00101 std::string copy_;
00102 absl::string_view value_;
00103 };
00104
00105
00106
00107
00108
00109
00110
00111 template <typename Splitter>
00112 class SplitIterator {
00113 public:
00114 using iterator_category = std::input_iterator_tag;
00115 using value_type = absl::string_view;
00116 using difference_type = ptrdiff_t;
00117 using pointer = const value_type*;
00118 using reference = const value_type&;
00119
00120 enum State { kInitState, kLastState, kEndState };
00121 SplitIterator(State state, const Splitter* splitter)
00122 : pos_(0),
00123 state_(state),
00124 splitter_(splitter),
00125 delimiter_(splitter->delimiter()),
00126 predicate_(splitter->predicate()) {
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 if (splitter_->text().data() == nullptr) {
00137 state_ = kEndState;
00138 pos_ = splitter_->text().size();
00139 return;
00140 }
00141
00142 if (state_ == kEndState) {
00143 pos_ = splitter_->text().size();
00144 } else {
00145 ++(*this);
00146 }
00147 }
00148
00149 bool at_end() const { return state_ == kEndState; }
00150
00151 reference operator*() const { return curr_; }
00152 pointer operator->() const { return &curr_; }
00153
00154 SplitIterator& operator++() {
00155 do {
00156 if (state_ == kLastState) {
00157 state_ = kEndState;
00158 return *this;
00159 }
00160 const absl::string_view text = splitter_->text();
00161 const absl::string_view d = delimiter_.Find(text, pos_);
00162 if (d.data() == text.data() + text.size()) state_ = kLastState;
00163 curr_ = text.substr(pos_, d.data() - (text.data() + pos_));
00164 pos_ += curr_.size() + d.size();
00165 } while (!predicate_(curr_));
00166 return *this;
00167 }
00168
00169 SplitIterator operator++(int) {
00170 SplitIterator old(*this);
00171 ++(*this);
00172 return old;
00173 }
00174
00175 friend bool operator==(const SplitIterator& a, const SplitIterator& b) {
00176 return a.state_ == b.state_ && a.pos_ == b.pos_;
00177 }
00178
00179 friend bool operator!=(const SplitIterator& a, const SplitIterator& b) {
00180 return !(a == b);
00181 }
00182
00183 private:
00184 size_t pos_;
00185 State state_;
00186 absl::string_view curr_;
00187 const Splitter* splitter_;
00188 typename Splitter::DelimiterType delimiter_;
00189 typename Splitter::PredicateType predicate_;
00190 };
00191
00192
00193 template <typename T, typename = void>
00194 struct HasMappedType : std::false_type {};
00195 template <typename T>
00196 struct HasMappedType<T, absl::void_t<typename T::mapped_type>>
00197 : std::true_type {};
00198
00199
00200 template <typename T, typename = void>
00201 struct HasValueType : std::false_type {};
00202 template <typename T>
00203 struct HasValueType<T, absl::void_t<typename T::value_type>> : std::true_type {
00204 };
00205
00206
00207 template <typename T, typename = void>
00208 struct HasConstIterator : std::false_type {};
00209 template <typename T>
00210 struct HasConstIterator<T, absl::void_t<typename T::const_iterator>>
00211 : std::true_type {};
00212
00213
00214
00215 std::false_type IsInitializerListDispatch(...);
00216 template <typename T>
00217 std::true_type IsInitializerListDispatch(std::initializer_list<T>*);
00218 template <typename T>
00219 struct IsInitializerList
00220 : decltype(IsInitializerListDispatch(static_cast<T*>(nullptr))) {};
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 template <typename C, bool has_value_type, bool has_mapped_type>
00233 struct SplitterIsConvertibleToImpl : std::false_type {};
00234
00235 template <typename C>
00236 struct SplitterIsConvertibleToImpl<C, true, false>
00237 : std::is_constructible<typename C::value_type, absl::string_view> {};
00238
00239 template <typename C>
00240 struct SplitterIsConvertibleToImpl<C, true, true>
00241 : absl::conjunction<
00242 std::is_constructible<typename C::key_type, absl::string_view>,
00243 std::is_constructible<typename C::mapped_type, absl::string_view>> {};
00244
00245 template <typename C>
00246 struct SplitterIsConvertibleTo
00247 : SplitterIsConvertibleToImpl<
00248 C,
00249 #ifdef _GLIBCXX_DEBUG
00250 !IsStrictlyBaseOfAndConvertibleToSTLContainer<C>::value &&
00251 #endif
00252 !IsInitializerList<
00253 typename std::remove_reference<C>::type>::value &&
00254 HasValueType<C>::value && HasConstIterator<C>::value,
00255 HasMappedType<C>::value> {
00256 };
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 template <typename Delimiter, typename Predicate>
00276 class Splitter {
00277 public:
00278 using DelimiterType = Delimiter;
00279 using PredicateType = Predicate;
00280 using const_iterator = strings_internal::SplitIterator<Splitter>;
00281 using value_type = typename std::iterator_traits<const_iterator>::value_type;
00282
00283 Splitter(ConvertibleToStringView input_text, Delimiter d, Predicate p)
00284 : text_(std::move(input_text)),
00285 delimiter_(std::move(d)),
00286 predicate_(std::move(p)) {}
00287
00288 absl::string_view text() const { return text_.value(); }
00289 const Delimiter& delimiter() const { return delimiter_; }
00290 const Predicate& predicate() const { return predicate_; }
00291
00292
00293
00294
00295 const_iterator begin() const { return {const_iterator::kInitState, this}; }
00296 const_iterator end() const { return {const_iterator::kEndState, this}; }
00297
00298
00299
00300 template <typename Container,
00301 typename = typename std::enable_if<
00302 SplitterIsConvertibleTo<Container>::value>::type>
00303 operator Container() const {
00304 return ConvertToContainer<Container, typename Container::value_type,
00305 HasMappedType<Container>::value>()(*this);
00306 }
00307
00308
00309
00310
00311
00312 template <typename First, typename Second>
00313 operator std::pair<First, Second>() const {
00314 absl::string_view first, second;
00315 auto it = begin();
00316 if (it != end()) {
00317 first = *it;
00318 if (++it != end()) {
00319 second = *it;
00320 }
00321 }
00322 return {First(first), Second(second)};
00323 }
00324
00325 private:
00326
00327
00328
00329
00330
00331
00332
00333 template <typename Container, typename ValueType, bool is_map = false>
00334 struct ConvertToContainer {
00335 Container operator()(const Splitter& splitter) const {
00336 Container c;
00337 auto it = std::inserter(c, c.end());
00338 for (const auto sp : splitter) {
00339 *it++ = ValueType(sp);
00340 }
00341 return c;
00342 }
00343 };
00344
00345
00346
00347
00348
00349
00350 template <typename A>
00351 struct ConvertToContainer<std::vector<absl::string_view, A>,
00352 absl::string_view, false> {
00353 std::vector<absl::string_view, A> operator()(
00354 const Splitter& splitter) const {
00355 struct raw_view {
00356 const char* data;
00357 size_t size;
00358 operator absl::string_view() const {
00359 return {data, size};
00360 }
00361 };
00362 std::vector<absl::string_view, A> v;
00363 std::array<raw_view, 16> ar;
00364 for (auto it = splitter.begin(); !it.at_end();) {
00365 size_t index = 0;
00366 do {
00367 ar[index].data = it->data();
00368 ar[index].size = it->size();
00369 ++it;
00370 } while (++index != ar.size() && !it.at_end());
00371 v.insert(v.end(), ar.begin(), ar.begin() + index);
00372 }
00373 return v;
00374 }
00375 };
00376
00377
00378
00379
00380
00381
00382
00383 template <typename A>
00384 struct ConvertToContainer<std::vector<std::string, A>, std::string, false> {
00385 std::vector<std::string, A> operator()(const Splitter& splitter) const {
00386 const std::vector<absl::string_view> v = splitter;
00387 return std::vector<std::string, A>(v.begin(), v.end());
00388 }
00389 };
00390
00391
00392
00393
00394
00395
00396
00397 template <typename Container, typename First, typename Second>
00398 struct ConvertToContainer<Container, std::pair<const First, Second>, true> {
00399 Container operator()(const Splitter& splitter) const {
00400 Container m;
00401 typename Container::iterator it;
00402 bool insert = true;
00403 for (const auto sp : splitter) {
00404 if (insert) {
00405 it = Inserter<Container>::Insert(&m, First(sp), Second());
00406 } else {
00407 it->second = Second(sp);
00408 }
00409 insert = !insert;
00410 }
00411 return m;
00412 }
00413
00414
00415
00416
00417 template <typename Map>
00418 struct Inserter {
00419 using M = Map;
00420 template <typename... Args>
00421 static typename M::iterator Insert(M* m, Args&&... args) {
00422 return m->insert(std::make_pair(std::forward<Args>(args)...)).first;
00423 }
00424 };
00425
00426 template <typename... Ts>
00427 struct Inserter<std::map<Ts...>> {
00428 using M = std::map<Ts...>;
00429 template <typename... Args>
00430 static typename M::iterator Insert(M* m, Args&&... args) {
00431 return m->emplace(std::make_pair(std::forward<Args>(args)...)).first;
00432 }
00433 };
00434
00435 template <typename... Ts>
00436 struct Inserter<std::multimap<Ts...>> {
00437 using M = std::multimap<Ts...>;
00438 template <typename... Args>
00439 static typename M::iterator Insert(M* m, Args&&... args) {
00440 return m->emplace(std::make_pair(std::forward<Args>(args)...));
00441 }
00442 };
00443 };
00444
00445 ConvertibleToStringView text_;
00446 Delimiter delimiter_;
00447 Predicate predicate_;
00448 };
00449
00450 }
00451 }
00452
00453 #endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_