// Copyright 2017 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // This file declares INTERNAL parts of the Split API that are inline/templated // or otherwise need to be available at compile time. The main abstractions // defined in here are // // - ConvertibleToStringView // - SplitIterator<> // - Splitter<> // // DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including // absl/strings/str_split.h. // // IWYU pragma: private, include "absl/strings/str_split.h" #ifndef ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ #define ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ #include <array> #include <cstddef> #include <initializer_list> #include <iterator> #include <tuple> #include <type_traits> #include <utility> #include <vector> #include "absl/base/macros.h" #include "absl/base/port.h" #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" #ifdef _GLIBCXX_DEBUG #include "absl/strings/internal/stl_type_traits.h" #endif // _GLIBCXX_DEBUG namespace absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { // This class is implicitly constructible from everything that absl::string_view // is implicitly constructible from, except for rvalue strings. This means it // can be used as a function parameter in places where passing a temporary // string might cause memory lifetime issues. class ConvertibleToStringView { … }; // An iterator that enumerates the parts of a string from a Splitter. The text // to be split, the Delimiter, and the Predicate are all taken from the given // Splitter object. Iterators may only be compared if they refer to the same // Splitter instance. // // This class is NOT part of the public splitting API. template <typename Splitter> class SplitIterator { … }; // HasMappedType<T>::value is true iff there exists a type T::mapped_type. template <typename T, typename = void> struct HasMappedType : std::false_type { … }; template <typename T> struct HasMappedType<T, absl::void_t<typename T::mapped_type>> : std::true_type {}; // HasValueType<T>::value is true iff there exists a type T::value_type. template <typename T, typename = void> struct HasValueType : std::false_type { … }; template <typename T> struct HasValueType<T, absl::void_t<typename T::value_type>> : std::true_type { }; // HasConstIterator<T>::value is true iff there exists a type T::const_iterator. template <typename T, typename = void> struct HasConstIterator : std::false_type { … }; template <typename T> struct HasConstIterator<T, absl::void_t<typename T::const_iterator>> : std::true_type {}; // HasEmplace<T>::value is true iff there exists a method T::emplace(). template <typename T, typename = void> struct HasEmplace : std::false_type { … }; template <typename T> struct HasEmplace<T, absl::void_t<decltype(std::declval<T>().emplace())>> : std::true_type {}; // IsInitializerList<T>::value is true iff T is an std::initializer_list. More // details below in Splitter<> where this is used. std::false_type IsInitializerListDispatch(...); // default: No template <typename T> std::true_type IsInitializerListDispatch(std::initializer_list<T>*); template <typename T> struct IsInitializerList : decltype(IsInitializerListDispatch(static_cast<T*>(nullptr))) { … }; // A SplitterIsConvertibleTo<C>::type alias exists iff the specified condition // is true for type 'C'. // // Restricts conversion to container-like types (by testing for the presence of // a const_iterator member type) and also to disable conversion to an // std::initializer_list (which also has a const_iterator). Otherwise, code // compiled in C++11 will get an error due to ambiguous conversion paths (in // C++11 std::vector<T>::operator= is overloaded to take either a std::vector<T> // or an std::initializer_list<T>). template <typename C, bool has_value_type, bool has_mapped_type> struct SplitterIsConvertibleToImpl : std::false_type { … }; SplitterIsConvertibleToImpl<C, true, false>; SplitterIsConvertibleToImpl<C, true, true>; template <typename C> struct SplitterIsConvertibleTo : SplitterIsConvertibleToImpl< C, #ifdef _GLIBCXX_DEBUG !IsStrictlyBaseOfAndConvertibleToSTLContainer<C>::value && #endif // _GLIBCXX_DEBUG !IsInitializerList< typename std::remove_reference<C>::type>::value && HasValueType<C>::value && HasConstIterator<C>::value, HasMappedType<C>::value> { … }; template <typename StringType, typename Container, typename = void> struct ShouldUseLifetimeBound : std::false_type { … }; template <typename StringType, typename Container> struct ShouldUseLifetimeBound< StringType, Container, std::enable_if_t< std::is_same<StringType, std::string>::value && std::is_same<typename Container::value_type, absl::string_view>::value>> : std::true_type {}; template <typename StringType, typename First, typename Second> using ShouldUseLifetimeBoundForPair = std::integral_constant< bool, std::is_same<StringType, std::string>::value && (std::is_same<First, absl::string_view>::value || std::is_same<Second, absl::string_view>::value)>; // This class implements the range that is returned by absl::StrSplit(). This // class has templated conversion operators that allow it to be implicitly // converted to a variety of types that the caller may have specified on the // left-hand side of an assignment. // // The main interface for interacting with this class is through its implicit // conversion operators. However, this class may also be used like a container // in that it has .begin() and .end() member functions. It may also be used // within a range-for loop. // // Output containers can be collections of any type that is constructible from // an absl::string_view. // // An Predicate functor may be supplied. This predicate will be used to filter // the split strings: only strings for which the predicate returns true will be // kept. A Predicate object is any unary functor that takes an absl::string_view // and returns bool. // // The StringType parameter can be either string_view or string, depending on // whether the Splitter refers to a string stored elsewhere, or if the string // resides inside the Splitter itself. template <typename Delimiter, typename Predicate, typename StringType> class Splitter { … }; } // namespace strings_internal ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_