From 1ef8a6a63b0171892c6ed7f08f6c9320f48ba11f Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 19 Feb 2013 02:49:10 +0900 Subject: [PATCH] add sprout::string_ref support conversion array-like container iterator to pointer --- libs/string/test/string.cpp | 3 +- libs/utility/string_ref/test/string_ref.cpp | 229 ++++++++ sprout/array/array.hpp | 4 +- sprout/bitset/bitset.hpp | 4 +- sprout/bitset/hash.hpp | 1 + sprout/cmath.hpp | 11 +- sprout/complex/hash.hpp | 1 + sprout/config/auto_config.hpp | 18 + sprout/config/compiler/borland.hpp | 1 + sprout/config/compiler/clang.hpp | 4 + sprout/config/compiler/codegear.hpp | 1 + sprout/config/compiler/common_edg.hpp | 1 + sprout/config/compiler/digitalmars.hpp | 1 + sprout/config/compiler/gcc.hpp | 4 + sprout/config/compiler/gcc_xml.hpp | 1 + sprout/config/compiler/has_future.hpp | 3 + sprout/config/compiler/metrowerks.hpp | 1 + sprout/config/compiler/mpw.hpp | 1 + sprout/config/compiler/no_cxx11_future.hpp | 3 + sprout/config/compiler/pathscale.hpp | 1 + sprout/config/compiler/pgi.hpp | 1 + sprout/config/compiler/sunpro_cc.hpp | 1 + sprout/config/compiler/vacpp.hpp | 7 +- sprout/config/compiler/visualc.hpp | 1 + sprout/config/suffix.hpp | 12 + sprout/container/container_traits.hpp | 4 +- sprout/container/sscrisk/cel/array.hpp | 4 +- .../iterator/detail/iterator_to_pointer.hpp | 21 + sprout/iterator/index_iterator.hpp | 32 +- sprout/iterator/ptr_index_iterator.hpp | 8 +- sprout/logic/tribool/hash.hpp | 1 + sprout/logic/tribool/io.hpp | 2 +- sprout/math/cmath.hpp | 16 + sprout/math/functions.hpp | 11 +- sprout/optional/hash.hpp | 1 + sprout/pit/hash.hpp | 1 + sprout/range/ptr_range.hpp | 24 +- sprout/rational/hash.hpp | 1 + sprout/string/detail/compare.hpp | 36 ++ sprout/string/detail/find.hpp | 231 ++++++++ sprout/string/detail/operations.hpp | 8 + sprout/string/hash.hpp | 1 + sprout/string/string.hpp | 252 ++------ sprout/sub_array/hash.hpp | 2 + sprout/tuple/tuple/hash.hpp | 1 + sprout/utility.hpp | 1 + sprout/utility/pair/hash.hpp | 1 + sprout/utility/string_ref.hpp | 12 + sprout/utility/string_ref/alias.hpp | 26 + sprout/utility/string_ref/comparison.hpp | 109 ++++ sprout/utility/string_ref/hash.hpp | 31 + sprout/utility/string_ref/io.hpp | 19 + sprout/utility/string_ref/string_ref.hpp | 555 ++++++++++++++++++ sprout/utility/string_ref/type_traits.hpp | 79 +++ sprout/utility/value_holder/hash.hpp | 1 + sprout/uuid/detail/table.hpp | 2 +- sprout/uuid/hash.hpp | 1 + sprout/uuid/uuid.hpp | 4 +- sprout/variant/hash.hpp | 1 + sprout/weed/detail/bdigits.hpp | 2 +- sprout/weed/detail/digits.hpp | 2 +- sprout/weed/detail/odigits.hpp | 2 +- sprout/weed/detail/xdigits.hpp | 2 +- testspr/sprout.cpp | 2 + 64 files changed, 1570 insertions(+), 254 deletions(-) create mode 100644 libs/utility/string_ref/test/string_ref.cpp create mode 100644 sprout/iterator/detail/iterator_to_pointer.hpp create mode 100644 sprout/math/cmath.hpp create mode 100644 sprout/string/detail/compare.hpp create mode 100644 sprout/string/detail/find.hpp create mode 100644 sprout/string/detail/operations.hpp create mode 100644 sprout/utility/string_ref.hpp create mode 100644 sprout/utility/string_ref/alias.hpp create mode 100644 sprout/utility/string_ref/comparison.hpp create mode 100644 sprout/utility/string_ref/hash.hpp create mode 100644 sprout/utility/string_ref/io.hpp create mode 100644 sprout/utility/string_ref/string_ref.hpp create mode 100644 sprout/utility/string_ref/type_traits.hpp diff --git a/libs/string/test/string.cpp b/libs/string/test/string.cpp index 1f881969..451b3cf2 100644 --- a/libs/string/test/string.cpp +++ b/libs/string/test/string.cpp @@ -1,7 +1,6 @@ #ifndef SPROUT_LIBS_STRING_TEST_STRING_CPP #define SPROUT_LIBS_STRING_TEST_STRING_CPP -#include #include #include #include @@ -48,7 +47,7 @@ namespace testspr { // empty TESTSPR_BOTH_ASSERT(!str1.empty()); - TESTSPR_BOTH_ASSERT((string_t<0>::type().empty())); + TESTSPR_BOTH_ASSERT((sprout::string_t<0>::type().empty())); // max_size TESTSPR_BOTH_ASSERT(str1.max_size() == 10); diff --git a/libs/utility/string_ref/test/string_ref.cpp b/libs/utility/string_ref/test/string_ref.cpp new file mode 100644 index 00000000..58d6135d --- /dev/null +++ b/libs/utility/string_ref/test/string_ref.cpp @@ -0,0 +1,229 @@ +#ifndef SPROUT_LIBS_UTILITY_STRING_REF_TEST_STRING_REF_CPP +#define SPROUT_LIBS_UTILITY_STRING_REF_TEST_STRING_REF_CPP + +#include +#include +#include +#include +#include +#include + +namespace testspr { + static void string_ref_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR char cstr[] = "foobar1234"; + SPROUT_STATIC_CONSTEXPR auto s = sprout::to_string("hogehoge"); + SPROUT_STATIC_CONSTEXPR auto str1 = sprout::string_ref(cstr); + SPROUT_STATIC_CONSTEXPR auto str2 = sprout::string_ref(s); + + // begin + TESTSPR_BOTH_ASSERT(cstr[0] == *str1.begin()); + + // cbegin + TESTSPR_BOTH_ASSERT(cstr[0] == *str1.cbegin()); + + // end + TESTSPR_BOTH_ASSERT(cstr[9] == *(str1.end() - 1)); + + // cend + TESTSPR_BOTH_ASSERT(cstr[9] == *(str1.cend() - 1)); + + // rbegin + TESTSPR_BOTH_ASSERT(cstr[9] == *str1.rbegin()); + + // crbegin + TESTSPR_BOTH_ASSERT(cstr[9] == *str1.crbegin()); + + // rend + TESTSPR_BOTH_ASSERT(cstr[0] == *(str1.rend() - 1)); + + // crend + TESTSPR_BOTH_ASSERT(cstr[0] == *(str1.crend() - 1)); + + // size + TESTSPR_BOTH_ASSERT(str1.size() == 10); + + // empty + TESTSPR_BOTH_ASSERT(!str1.empty()); + TESTSPR_BOTH_ASSERT((sprout::string_ref().empty())); + + // max_size + TESTSPR_BOTH_ASSERT(str1.max_size() == 10); + + // operator[] + TESTSPR_BOTH_ASSERT(cstr[0] == str1[0]); + + // at + TESTSPR_BOTH_ASSERT(cstr[0] == str1.at(0)); + + // front + TESTSPR_BOTH_ASSERT(cstr[0] == str1.front()); + + // back + TESTSPR_BOTH_ASSERT(cstr[9] == str1.back()); + + // data + TESTSPR_BOTH_ASSERT(cstr[0] == *str1.data()); + + // c_str + TESTSPR_BOTH_ASSERT(cstr[0] == *str1.c_str()); + + // swap + { + auto s1 = sprout::string_ref("abc"); + auto s2 = sprout::string_ref("ABC"); + s1.swap(s2); + TESTSPR_ASSERT(s1[0] == 'A'); + } + + // operator= + { + auto s = sprout::string_ref("abc"); + s = sprout::string_ref("ABC"); + TESTSPR_ASSERT(s.size() == 3); + TESTSPR_ASSERT(s[0] == 'A'); + } + { + auto s = sprout::to_string("abc"); + s = "ABC"; + TESTSPR_ASSERT(s.size() == 3); + TESTSPR_ASSERT(s[0] == 'A'); + } + { + auto s = sprout::to_string("abc"); + s = 'A'; + TESTSPR_ASSERT(s.size() == 1); + TESTSPR_ASSERT(s[0] == 'A'); + } + + // find + TESTSPR_BOTH_ASSERT(str1.find(str2) == npos); + TESTSPR_BOTH_ASSERT(str1.find(sprout::string_ref("bar")) == 3); + TESTSPR_BOTH_ASSERT(str1.find(str2.c_str()) == npos); + TESTSPR_BOTH_ASSERT(str1.find("bar") == 3); + TESTSPR_BOTH_ASSERT(str1.find(str2.c_str(), 0, 3) == npos); + TESTSPR_BOTH_ASSERT(str1.find("barbar", 0, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.find('b') == 3); + + // rfind + TESTSPR_BOTH_ASSERT(str1.rfind(str2) == npos); + TESTSPR_BOTH_ASSERT(str1.rfind(sprout::string_ref("bar")) == 3); + TESTSPR_BOTH_ASSERT(str1.rfind(str2.c_str()) == npos); + TESTSPR_BOTH_ASSERT(str1.rfind("bar") == 3); + TESTSPR_BOTH_ASSERT(str1.rfind(str2.c_str(), npos, 3) == npos); + TESTSPR_BOTH_ASSERT(str1.rfind("barbar", npos, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.rfind('b') == 3); + + // find_first_of + TESTSPR_BOTH_ASSERT(str1.find_first_of(sprout::string_ref("vwxyz")) == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_of(sprout::string_ref("rab")) == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_of("vwxyz") == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_of("rab") == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_of("vwxyz", 0, 3) == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_of("rabrab", 0, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_of('b') == 3); + + // find_last_of + TESTSPR_BOTH_ASSERT(str1.find_last_of(sprout::string_ref("vwxyz")) == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_of(sprout::string_ref("rab")) == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_of("vwxyz") == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_of("rab") == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_of("vwxyz", npos, 3) == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_of("rabrab", npos, 3) == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_of('r') == 5); + + // find_first_not_of + TESTSPR_BOTH_ASSERT(str1.find_first_not_of(str1) == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of(sprout::string_ref("foo")) == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of(str1.c_str()) == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of("foo") == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of(str1.c_str(), 0, 10) == npos); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of("foofoo", 0, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.find_first_not_of('f') == 1); + + // find_last_not_of + TESTSPR_BOTH_ASSERT(str1.find_last_not_of(str1) == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of(sprout::string_ref("4321")) == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of(str1.c_str()) == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of("4321") == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of(str1.c_str(), npos, 10) == npos); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of("43214321", npos, 4) == 5); + TESTSPR_BOTH_ASSERT(str1.find_last_not_of('4') == 8); + + // substr + { + SPROUT_STATIC_CONSTEXPR auto str3 = str1.substr(); + TESTSPR_BOTH_ASSERT(str3 == "foobar1234"); + } + { + SPROUT_STATIC_CONSTEXPR auto str3 = str1.substr(6); + TESTSPR_BOTH_ASSERT(str3 == "1234"); + } + { + SPROUT_STATIC_CONSTEXPR auto str3 = str1.substr(0, 6); + TESTSPR_BOTH_ASSERT(str3 == "foobar"); + } + + // compare + TESTSPR_BOTH_ASSERT(str1.compare(str1) == 0); + TESTSPR_BOTH_ASSERT(str1.compare(sprout::string_ref("zzzz")) < 0); + TESTSPR_BOTH_ASSERT(str2.compare(sprout::string_ref("aaaa")) > 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, sprout::string_ref("foo")) == 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, sprout::string_ref("zzzz")) < 0); + TESTSPR_BOTH_ASSERT(str2.compare(0, 3, sprout::string_ref("aaaa")) > 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, sprout::string_ref("foo"), 0, 3) == 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, sprout::string_ref("zzzz"), 0, 3) < 0); + TESTSPR_BOTH_ASSERT(str2.compare(0, 3, sprout::string_ref("aaaa"), 0, 3) > 0); + TESTSPR_BOTH_ASSERT(str1.compare(str1.c_str()) == 0); + TESTSPR_BOTH_ASSERT(str1.compare("zzzz") < 0); + TESTSPR_BOTH_ASSERT(str1.compare("aaaa") > 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "foo") == 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "zzzz") < 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "aaaa") > 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "foo", 3) == 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "zzzz", 3) < 0); + TESTSPR_BOTH_ASSERT(str1.compare(0, 3, "aaaa", 3) > 0); + + // operator== + TESTSPR_BOTH_ASSERT(!(str1 == str2)); + + // operator!= + TESTSPR_BOTH_ASSERT(str1 != str2); + + // operator< + TESTSPR_BOTH_ASSERT(str1 < str2); + + // operator> + TESTSPR_BOTH_ASSERT(!(str1 > str2)); + + // operator<= + TESTSPR_BOTH_ASSERT(str1 <= str2); + + // operator>= + TESTSPR_BOTH_ASSERT(!(str1 >= str2)); + + // operator<< + { + std::ostringstream os; + os << str1; + TESTSPR_ASSERT(os.str() == cstr); + } + + // is_string_ref + TESTSPR_BOTH_ASSERT(sprout::is_string_ref::value); + TESTSPR_BOTH_ASSERT(!sprout::is_string_ref::value); + + // sprout::to_hash, sprout::hash + TESTSPR_BOTH_ASSERT(sprout::to_hash(str1) == sprout::hash()(str1)); + TESTSPR_BOTH_ASSERT(sprout::to_hash(str1) != sprout::to_hash(str2)); + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::string_ref_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_UTILITY_STRING_REF_TEST_STRING_REF_CPP diff --git a/sprout/array/array.hpp b/sprout/array/array.hpp index 459d235d..6935d2e4 100644 --- a/sprout/array/array.hpp +++ b/sprout/array/array.hpp @@ -24,8 +24,8 @@ namespace sprout { public: typedef T value_type; #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - typedef sprout::index_iterator iterator; - typedef sprout::index_iterator const_iterator; + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; #else typedef T* iterator; typedef T const* const_iterator; diff --git a/sprout/bitset/bitset.hpp b/sprout/bitset/bitset.hpp index eb543dd2..1d166150 100644 --- a/sprout/bitset/bitset.hpp +++ b/sprout/bitset/bitset.hpp @@ -33,8 +33,8 @@ namespace sprout { public: typedef unsigned long word_type; typedef word_type value_type; - typedef sprout::index_iterator iterator; - typedef sprout::index_iterator const_iterator; + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; typedef value_type& reference; typedef value_type const& const_reference; typedef std::size_t size_type; diff --git a/sprout/bitset/hash.hpp b/sprout/bitset/hash.hpp index 8632660a..4d923853 100644 --- a/sprout/bitset/hash.hpp +++ b/sprout/bitset/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_BITSET_HASH_HPP #include +#include #include #include diff --git a/sprout/cmath.hpp b/sprout/cmath.hpp index a4a20dcd..ecdbd98b 100644 --- a/sprout/cmath.hpp +++ b/sprout/cmath.hpp @@ -2,15 +2,6 @@ #define SPROUT_CMATH_HPP #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #endif // #ifndef SPROUT_CMATH_HPP diff --git a/sprout/complex/hash.hpp b/sprout/complex/hash.hpp index 1218477c..a99b80e4 100644 --- a/sprout/complex/hash.hpp +++ b/sprout/complex/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_COMPLEX_HASH_HPP #include +#include #include #include #include diff --git a/sprout/config/auto_config.hpp b/sprout/config/auto_config.hpp index b7524272..74a786c5 100644 --- a/sprout/config/auto_config.hpp +++ b/sprout/config/auto_config.hpp @@ -30,6 +30,15 @@ # endif // #ifdef SPROUT_NO_CONSTEXPR #endif // #ifndef SPROUT_CONFIG_DISABLE_DELETED_FUNCTIONS +// +// SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS +// +#ifndef SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS +# ifdef SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS +# endif // #ifdef SPROUT_NO_CONSTEXPR +#endif // #ifndef SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS + // // SPROUT_CONFIG_DISABLE_NOEXCEPT // @@ -66,6 +75,15 @@ # endif // #ifdef SPROUT_NO_DELEGATING_CONSTRUCTORS #endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +// +// SPROUT_CONFIG_DISABLE_UNICODE_LITERALS +// +#ifndef SPROUT_CONFIG_DISABLE_UNICODE_LITERALS +# ifdef SPROUT_NO_UNICODE_LITERALS +# define SPROUT_CONFIG_DISABLE_UNICODE_LITERALS +# endif // #ifdef SPROUT_NO_UNICODE_LITERALS +#endif // #ifndef SPROUT_CONFIG_DISABLE_UNICODE_LITERALS + // // SPROUT_CONFIG_USE_SSCRISK_CEL // diff --git a/sprout/config/compiler/borland.hpp b/sprout/config/compiler/borland.hpp index 3a99b77c..4c32d2cc 100644 --- a/sprout/config/compiler/borland.hpp +++ b/sprout/config/compiler/borland.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/clang.hpp b/sprout/config/compiler/clang.hpp index cbd59164..3abdb8dc 100644 --- a/sprout/config/compiler/clang.hpp +++ b/sprout/config/compiler/clang.hpp @@ -13,6 +13,10 @@ # define SPROUT_NO_DELETED_FUNCTIONS #endif +#if !__has_feature(cxx_explicit_conversions) +# define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +#endif + #if !__has_feature(cxx_noexcept) # define SPROUT_NO_NOEXCEPT #endif diff --git a/sprout/config/compiler/codegear.hpp b/sprout/config/compiler/codegear.hpp index ba3d1f2c..e45f89d6 100644 --- a/sprout/config/compiler/codegear.hpp +++ b/sprout/config/compiler/codegear.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/common_edg.hpp b/sprout/config/compiler/common_edg.hpp index 840e6a36..d6343fb9 100644 --- a/sprout/config/compiler/common_edg.hpp +++ b/sprout/config/compiler/common_edg.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/digitalmars.hpp b/sprout/config/compiler/digitalmars.hpp index 1b557a87..e42a781c 100644 --- a/sprout/config/compiler/digitalmars.hpp +++ b/sprout/config/compiler/digitalmars.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/gcc.hpp b/sprout/config/compiler/gcc.hpp index 4ef18e52..6edc250e 100644 --- a/sprout/config/compiler/gcc.hpp +++ b/sprout/config/compiler/gcc.hpp @@ -13,6 +13,10 @@ # define SPROUT_NO_DELETED_FUNCTIONS #endif +#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)) +# define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +#endif + #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) || !defined(__GXX_EXPERIMENTAL_CXX0X__)) # define SPROUT_NO_NOEXCEPT #endif diff --git a/sprout/config/compiler/gcc_xml.hpp b/sprout/config/compiler/gcc_xml.hpp index 94e46e05..c4d60533 100644 --- a/sprout/config/compiler/gcc_xml.hpp +++ b/sprout/config/compiler/gcc_xml.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/has_future.hpp b/sprout/config/compiler/has_future.hpp index fcfd30fc..296fd6c8 100644 --- a/sprout/config/compiler/has_future.hpp +++ b/sprout/config/compiler/has_future.hpp @@ -10,6 +10,9 @@ #ifndef SPROUT_NO_DELETED_FUNCTIONS # define SPROUT_HAS_DELETED_FUNCTIONS #endif +#ifndef SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_HAS_EXPLICIT_CONVERSION_OPERATORS +#endif #ifndef SPROUT_NO_NOEXCEPT # define SPROUT_HAS_NOEXCEPT #endif diff --git a/sprout/config/compiler/metrowerks.hpp b/sprout/config/compiler/metrowerks.hpp index 81d64661..ac52eb7c 100644 --- a/sprout/config/compiler/metrowerks.hpp +++ b/sprout/config/compiler/metrowerks.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/mpw.hpp b/sprout/config/compiler/mpw.hpp index cf4b4202..35089da0 100644 --- a/sprout/config/compiler/mpw.hpp +++ b/sprout/config/compiler/mpw.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/no_cxx11_future.hpp b/sprout/config/compiler/no_cxx11_future.hpp index 0bba44f6..122a0cb7 100644 --- a/sprout/config/compiler/no_cxx11_future.hpp +++ b/sprout/config/compiler/no_cxx11_future.hpp @@ -10,6 +10,9 @@ #ifdef SPROUT_NO_DELETED_FUNCTIONS # define SPROUT_NO_CXX11_DELETED_FUNCTIONS #endif +#ifdef SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif #ifdef SPROUT_NO_NOEXCEPT # define SPROUT_NO_CXX11_NOEXCEPT #endif diff --git a/sprout/config/compiler/pathscale.hpp b/sprout/config/compiler/pathscale.hpp index 826ef01b..3ae11de7 100644 --- a/sprout/config/compiler/pathscale.hpp +++ b/sprout/config/compiler/pathscale.hpp @@ -5,6 +5,7 @@ # define SPROUT_NO_CONSTEXPR # define SPROUT_NO_DEFAULTED_FUNCTIONS # define SPROUT_NO_DELETED_FUNCTIONS +# define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS # define SPROUT_NO_NOEXCEPT # define SPROUT_NO_TEMPLATE_ALIASES # define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/pgi.hpp b/sprout/config/compiler/pgi.hpp index c9a2fac3..c08ccf04 100644 --- a/sprout/config/compiler/pgi.hpp +++ b/sprout/config/compiler/pgi.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/sunpro_cc.hpp b/sprout/config/compiler/sunpro_cc.hpp index b0d458fe..c4d91638 100644 --- a/sprout/config/compiler/sunpro_cc.hpp +++ b/sprout/config/compiler/sunpro_cc.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/vacpp.hpp b/sprout/config/compiler/vacpp.hpp index a95b07f7..29159b77 100644 --- a/sprout/config/compiler/vacpp.hpp +++ b/sprout/config/compiler/vacpp.hpp @@ -1,9 +1,14 @@ #ifndef SPROUT_CONFIG_COMPILER_VACPP_HPP #define SPROUT_CONFIG_COMPILER_VACPP_HPP -#define SPROUT_NO_CONSTEXPR +#if !__IBMCPP_CONSTEXPR +# define SPROUT_NO_CONSTEXPR +#endif #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#if !__IBMCPP_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS +#endif #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/compiler/visualc.hpp b/sprout/config/compiler/visualc.hpp index 4dfec04b..ee26fdff 100644 --- a/sprout/config/compiler/visualc.hpp +++ b/sprout/config/compiler/visualc.hpp @@ -4,6 +4,7 @@ #define SPROUT_NO_CONSTEXPR #define SPROUT_NO_DEFAULTED_FUNCTIONS #define SPROUT_NO_DELETED_FUNCTIONS +#define SPROUT_NO_EXPLICIT_CONVERSION_OPERATORS #define SPROUT_NO_NOEXCEPT #define SPROUT_NO_TEMPLATE_ALIASES #define SPROUT_NO_USER_DEFINED_LITERALS diff --git a/sprout/config/suffix.hpp b/sprout/config/suffix.hpp index 81e6cf3b..8283103b 100644 --- a/sprout/config/suffix.hpp +++ b/sprout/config/suffix.hpp @@ -31,6 +31,12 @@ # define SPROUT_DELETED_FUNCTION_DECL ; #endif // #ifndef SPROUT_CONFIG_DISABLE_DELETED_FUNCTIONS +#ifndef SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_USE_EXPLICIT_CONVERSION_OPERATORS 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS +# define SPROUT_USE_EXPLICIT_CONVERSION_OPERATORS 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_EXPLICIT_CONVERSION_OPERATORS + #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT # define SPROUT_NOEXCEPT noexcept # define SPROUT_NOEXCEPT_EXPR(EXPR) noexcept(EXPR) @@ -59,6 +65,12 @@ # define SPROUT_USE_DELEGATING_CONSTRUCTORS 0 #endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +#ifndef SPROUT_CONFIG_DISABLE_UNICODE_LITERALS +# define SPROUT_USE_UNICODE_LITERALS 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_UNICODE_LITERALS +# define SPROUT_USE_UNICODE_LITERALS 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_UNICODE_LITERALS + #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL # define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT # define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT diff --git a/sprout/container/container_traits.hpp b/sprout/container/container_traits.hpp index d3854d24..5f4d53eb 100644 --- a/sprout/container/container_traits.hpp +++ b/sprout/container/container_traits.hpp @@ -432,8 +432,8 @@ namespace sprout { public: typedef T value_type; #if SPROUT_USE_PTR_INDEX_ITERATOR_IMPLEMENTATION - typedef sprout::ptr_index_iterator iterator; - typedef sprout::ptr_index_iterator const_iterator; + typedef sprout::ptr_index_iterator iterator; + typedef sprout::ptr_index_iterator const_iterator; #else typedef T* iterator; typedef T const* const_iterator; diff --git a/sprout/container/sscrisk/cel/array.hpp b/sprout/container/sscrisk/cel/array.hpp index 0d0e297b..d5471b15 100644 --- a/sprout/container/sscrisk/cel/array.hpp +++ b/sprout/container/sscrisk/cel/array.hpp @@ -20,8 +20,8 @@ namespace sprout { : public sprout::detail::container_traits_default > { public: - typedef sprout::index_iterator&> iterator; - typedef sprout::index_iterator const&> const_iterator; + typedef sprout::index_iterator&, true> iterator; + typedef sprout::index_iterator const&, true> const_iterator; }; } // namespace sprout diff --git a/sprout/iterator/detail/iterator_to_pointer.hpp b/sprout/iterator/detail/iterator_to_pointer.hpp new file mode 100644 index 00000000..0f819915 --- /dev/null +++ b/sprout/iterator/detail/iterator_to_pointer.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_ITERATOR_DETAIL_ITERATOR_TO_POINTER_HPP +#define SPROUT_ITERATOR_DETAIL_ITERATOR_TO_POINTER_HPP + +#include +#include + +namespace sprout { + namespace detail { + template + class iterator_to_pointer_base {}; + template + class iterator_to_pointer_base { + public: + SPROUT_CONSTEXPR operator Pointer() const { + return &*static_cast(*this); + } + }; + } // namespace detail +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_DETAIL_ITERATOR_TO_POINTER_HPP diff --git a/sprout/iterator/index_iterator.hpp b/sprout/iterator/index_iterator.hpp index 2fe91cdd..92432954 100644 --- a/sprout/iterator/index_iterator.hpp +++ b/sprout/iterator/index_iterator.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,7 +17,7 @@ namespace sprout { // // index_iterator // - template + template class index_iterator : public std::iterator< std::random_access_iterator_tag, @@ -33,6 +34,15 @@ namespace sprout { typename sprout::container_traits::type>::reference >::type > + , public sprout::detail::iterator_to_pointer_base< + sprout::index_iterator, + typename std::conditional< + std::is_const::type>::value, + typename sprout::container_traits::type>::const_pointer, + typename sprout::container_traits::type>::pointer + >::type, + ConvertibleToPointer + > { public: typedef Container container_type; @@ -183,9 +193,9 @@ namespace sprout { // // swap // - template + template inline void - swap(sprout::index_iterator& lhs, sprout::index_iterator& rhs) + swap(sprout::index_iterator& lhs, sprout::index_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { lhs.swap(rhs); @@ -206,26 +216,26 @@ namespace sprout { struct is_index_iterator : public sprout::is_index_iterator {}; - template - struct is_index_iterator > + template + struct is_index_iterator > : public std::true_type {}; // // iterator_next // - template - inline SPROUT_CONSTEXPR sprout::index_iterator - iterator_next(sprout::index_iterator const& it) { + template + inline SPROUT_CONSTEXPR sprout::index_iterator + iterator_next(sprout::index_iterator const& it) { return it.next(); } // // iterator_prev // - template - inline SPROUT_CONSTEXPR sprout::index_iterator - iterator_prev(sprout::index_iterator const& it) { + template + inline SPROUT_CONSTEXPR sprout::index_iterator + iterator_prev(sprout::index_iterator const& it) { return it.prev(); } } // namespace sprout diff --git a/sprout/iterator/ptr_index_iterator.hpp b/sprout/iterator/ptr_index_iterator.hpp index 9e3d2a19..5f6ff3af 100644 --- a/sprout/iterator/ptr_index_iterator.hpp +++ b/sprout/iterator/ptr_index_iterator.hpp @@ -8,13 +8,14 @@ #include #include #include +#include #include namespace sprout { // // ptr_index_iterator // - template + template class ptr_index_iterator : public std::iterator< typename std::iterator_traits::iterator_category, @@ -23,6 +24,11 @@ namespace sprout { typename std::iterator_traits::pointer, typename std::iterator_traits::reference > + , public sprout::detail::iterator_to_pointer_base< + sprout::ptr_index_iterator, + typename std::iterator_traits::pointer, + ConvertibleToPointer + > { public: typedef T type; diff --git a/sprout/logic/tribool/hash.hpp b/sprout/logic/tribool/hash.hpp index ea91a4d9..f1a7b198 100644 --- a/sprout/logic/tribool/hash.hpp +++ b/sprout/logic/tribool/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_LOGIC_TRIBOOL_HASH_HPP #include +#include #include #include #include diff --git a/sprout/logic/tribool/io.hpp b/sprout/logic/tribool/io.hpp index fc47e96a..8b4a4497 100644 --- a/sprout/logic/tribool/io.hpp +++ b/sprout/logic/tribool/io.hpp @@ -27,7 +27,7 @@ namespace sprout { get_default_indeterminate_name() { return L"indeterminate"; } -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> inline std::basic_string get_default_indeterminate_name() { diff --git a/sprout/math/cmath.hpp b/sprout/math/cmath.hpp new file mode 100644 index 00000000..a160068b --- /dev/null +++ b/sprout/math/cmath.hpp @@ -0,0 +1,16 @@ +#ifndef SPROUT_MATH_CMATH_HPP +#define SPROUT_MATH_CMATH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_MATH_CMATH_HPP diff --git a/sprout/math/functions.hpp b/sprout/math/functions.hpp index baedfc21..5787ad10 100644 --- a/sprout/math/functions.hpp +++ b/sprout/math/functions.hpp @@ -2,16 +2,7 @@ #define SPROUT_MATH_FUNCTIONS_HPP #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include #include diff --git a/sprout/optional/hash.hpp b/sprout/optional/hash.hpp index f5437df6..cb4e08bd 100644 --- a/sprout/optional/hash.hpp +++ b/sprout/optional/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_OPTIONAL_HASH_HPP #include +#include #include #include #include diff --git a/sprout/pit/hash.hpp b/sprout/pit/hash.hpp index 9fb0c57b..114e06e5 100644 --- a/sprout/pit/hash.hpp +++ b/sprout/pit/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_PIT_HASH_HPP #include +#include #include #include #include diff --git a/sprout/range/ptr_range.hpp b/sprout/range/ptr_range.hpp index 6382f25e..565a8aaa 100644 --- a/sprout/range/ptr_range.hpp +++ b/sprout/range/ptr_range.hpp @@ -14,29 +14,29 @@ namespace sprout { // make_ptr_range // template - inline SPROUT_CONSTEXPR sprout::range::range_container > + inline SPROUT_CONSTEXPR sprout::range::range_container > make_ptr_range(T* p, typename std::iterator_traits::difference_type n) { - return sprout::range::range_container >( - sprout::ptr_index_iterator(p), - sprout::ptr_index_iterator(p, n) + return sprout::range::range_container >( + sprout::ptr_index_iterator(p), + sprout::ptr_index_iterator(p, n) ); } template - inline SPROUT_CONSTEXPR sprout::range::range_container > + inline SPROUT_CONSTEXPR sprout::range::range_container > make_ptr_range(T* first, T* last) { - return sprout::range::range_container >( - sprout::ptr_index_iterator(first), - sprout::ptr_index_iterator(first, sprout::distance(first, last)) + return sprout::range::range_container >( + sprout::ptr_index_iterator(first), + sprout::ptr_index_iterator(first, sprout::distance(first, last)) ); } template - inline SPROUT_CONSTEXPR sprout::range::range_container > + inline SPROUT_CONSTEXPR sprout::range::range_container > make_ptr_range(T (& arr)[N]) { - return sprout::range::range_container >( - sprout::ptr_index_iterator(arr), - sprout::ptr_index_iterator(arr, N) + return sprout::range::range_container >( + sprout::ptr_index_iterator(arr), + sprout::ptr_index_iterator(arr, N) ); } } // namespace range diff --git a/sprout/rational/hash.hpp b/sprout/rational/hash.hpp index e02234a0..e27be609 100644 --- a/sprout/rational/hash.hpp +++ b/sprout/rational/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_RATIONAL_HASH_HPP #include +#include #include #include #include diff --git a/sprout/string/detail/compare.hpp b/sprout/string/detail/compare.hpp new file mode 100644 index 00000000..f1ed197b --- /dev/null +++ b/sprout/string/detail/compare.hpp @@ -0,0 +1,36 @@ +#ifndef SPROUT_STRING_DETAIL_COMPARE_HPP +#define SPROUT_STRING_DETAIL_COMPARE_HPP + +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + namespace string_detail { + template + static SPROUT_CONSTEXPR int + compare_impl_1( + int compared, typename String::size_type n1, typename String::size_type n2 + ) + { + return compared != 0 ? compared + : n1 < n2 ? -1 + : n2 < n1 ? 1 + : 0 + ; + } + template + static SPROUT_CONSTEXPR int + compare_impl( + typename String::const_iterator data, typename String::size_type pos1, typename String::size_type n1, + ConstIterator s, typename String::size_type n2 + ) + { + return sprout::string_detail::compare_impl_1( + String::traits_type::compare(data + pos1, s, NS_SSCRISK_CEL_OR_SPROUT::min(n1, n2)), + n1, n2 + ); + } + } // namespace string_detail +} // namespace sprout + +#endif // #ifndef SPROUT_STRING_DETAIL_COMPARE_HPP diff --git a/sprout/string/detail/find.hpp b/sprout/string/detail/find.hpp new file mode 100644 index 00000000..34cb1a8b --- /dev/null +++ b/sprout/string/detail/find.hpp @@ -0,0 +1,231 @@ +#ifndef SPROUT_STRING_DETAIL_FIND_HPP +#define SPROUT_STRING_DETAIL_FIND_HPP + +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + namespace string_detail { + template + static SPROUT_CONSTEXPR typename String::size_type + find_impl_1( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return pos <= len - n + ? String::traits_type::eq(data[pos], *s) && String::traits_type::compare(data + (pos + 1), s + 1, n - 1) == 0 + ? pos + : sprout::string_detail::find_impl_1(data, len, s, pos + 1, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return n == 0 ? (pos <= len ? pos : String::npos) + : n <= len ? sprout::string_detail::find_impl_1(data, len, s, pos, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_c_impl_1( + typename String::const_iterator data, typename String::size_type len, + typename String::const_iterator p + ) + { + return sprout::char_traits_helper::is_found(p, data + len) ? p - data + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_c_impl( + typename String::const_iterator data, typename String::size_type len, + typename String::value_type c, typename String::size_type pos + ) + { + return pos < len ? sprout::string_detail::find_c_impl_1( + data, len, sprout::char_traits_helper::find(data + pos, len - pos, c) + ) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + rfind_impl_1( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return String::traits_type::compare(data + pos, s, n) == 0 ? pos + : pos > 0 ? sprout::string_detail::rfind_impl_1(data, len, s, pos - 1, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + rfind_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return n <= len ? sprout::string_detail::rfind_impl_1( + data, len, s, NS_SSCRISK_CEL_OR_SPROUT::min(typename String::size_type(len - n), pos), n + ) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + rfind_c_impl_1( + typename String::const_iterator data, typename String::size_type len, typename String::value_type c + ) + { + return len > 0 + ? String::traits_type::eq(data[len - 1], c) + ? len - 1 + : sprout::string_detail::rfind_c_impl_1(data, len - 1, c) + : String::npos + ; + } + + template + static SPROUT_CONSTEXPR typename String::size_type + rfind_c_impl( + typename String::const_iterator data, typename String::size_type len, + typename String::value_type c, typename String::size_type pos + ) + { + return len ? sprout::string_detail::rfind_c_impl_1(data, len - 1 > pos ? pos + 1 : len, c) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_first_of_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return n && pos < len + ? sprout::char_traits_helper::is_found( + sprout::char_traits_helper::find(s, n, data[pos]), s + n + ) + ? pos + : sprout::string_detail::find_first_of_impl(data, len, s, pos + 1, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_of_impl_1( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return sprout::char_traits_helper::is_found( + sprout::char_traits_helper::find(s, n, data[len]), s + n + ) ? len + : len ? sprout::string_detail::find_last_of_impl_1(data, len - 1, s, pos, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_of_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return len && n ? sprout::string_detail::find_last_of_impl_1(data, len - 1 > pos ? pos : len - 1, s, pos, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_first_not_of_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return pos < len + ? !sprout::char_traits_helper::is_found( + sprout::char_traits_helper::find(s, n, data[pos]), s + n + ) + ? pos + : sprout::string_detail::find_first_not_of_impl(data, len, s, pos + 1, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_first_not_of_c_impl( + typename String::const_iterator data, typename String::size_type len, + typename String::value_type c, typename String::size_type pos + ) + { + return pos < len ? !String::traits_type::eq(data[pos], c) + ? pos + : sprout::string_detail::find_first_not_of_c_impl(data, len, c, pos + 1) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_not_of_impl_1( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return !sprout::char_traits_helper::is_found( + sprout::char_traits_helper::find(s, n, data[len]), s + n + ) ? len + : len ? sprout::string_detail::find_last_not_of_impl_1(data, len - 1, s, pos, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_not_of_impl( + typename String::const_iterator data, typename String::size_type len, + ConstIterator s, typename String::size_type pos, typename String::size_type n + ) + { + return len ? sprout::string_detail::find_last_not_of_impl_1(data, len - 1 > pos ? pos : len - 1, s, pos, n) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_not_of_c_impl_1( + typename String::const_iterator data, typename String::size_type len, + typename String::value_type c, typename String::size_type pos + ) + { + return !String::traits_type::eq(data[len], c) ? len + : len ? sprout::string_detail::find_last_not_of_c_impl_1(data, len - 1, c, pos) + : String::npos + ; + } + template + static SPROUT_CONSTEXPR typename String::size_type + find_last_not_of_c_impl( + typename String::const_iterator data, typename String::size_type len, + typename String::value_type c, typename String::size_type pos + ) + { + return len ? sprout::string_detail::find_last_not_of_c_impl_1(data, len - 1 > pos ? pos : len - 1, c, pos) + : String::npos + ; + } + } // namespace string_detail +} // namespace sprout + +#endif // #ifndef SPROUT_STRING_DETAIL_FIND_HPP diff --git a/sprout/string/detail/operations.hpp b/sprout/string/detail/operations.hpp new file mode 100644 index 00000000..39dd5624 --- /dev/null +++ b/sprout/string/detail/operations.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_STRING_DETAIL_OPERATIONS_HPP +#define SPROUT_STRING_DETAIL_OPERATIONS_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_STRING_DETAIL_OPERATIONS_HPP diff --git a/sprout/string/hash.hpp b/sprout/string/hash.hpp index 07bb94be..7d6e926d 100644 --- a/sprout/string/hash.hpp +++ b/sprout/string/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_STRING_HASH_HPP #include +#include #include #include #include diff --git a/sprout/string/string.hpp b/sprout/string/string.hpp index e4853a61..a42df432 100644 --- a/sprout/string/string.hpp +++ b/sprout/string/string.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION # include @@ -31,8 +32,8 @@ namespace sprout { public: typedef T value_type; #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - typedef sprout::index_iterator iterator; - typedef sprout::index_iterator const_iterator; + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; #else typedef T* iterator; typedef T const* const_iterator; @@ -46,7 +47,6 @@ namespace sprout { typedef sprout::reverse_iterator reverse_iterator; typedef sprout::reverse_iterator const_reverse_iterator; typedef Traits traits_type; - typedef sprout::char_traits_helper traits_helper_type; #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION private: template @@ -66,11 +66,11 @@ namespace sprout { : public is_string_iterator {}; template - class is_string_iterator&> > + class is_string_iterator&, true> > : public std::true_type {}; template - class is_string_iterator const&> > + class is_string_iterator const&, true> > : public std::true_type {}; #endif @@ -78,127 +78,6 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR size_type npos = sprout::npos; SPROUT_STATIC_CONSTEXPR size_type static_size = N; private: - template - static SPROUT_CONSTEXPR size_type - find_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return pos <= len - n - ? traits_type::eq(data[pos], *s) && traits_type::compare(data + (pos + 1), s + 1, n - 1) == 0 - ? pos - : find_impl_1(data, len, s, pos + 1, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return n == 0 ? (pos <= len ? pos : npos) - : n <= len ? find_impl_1(data, len, s, pos, n) - : npos - ; - } - static SPROUT_CONSTEXPR size_type - find_c_impl(const_iterator p, const_iterator first, const_iterator last) { - return traits_helper_type::is_found(p, last) ? p - first - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - rfind_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return traits_type::compare(data + pos, s, n) == 0 ? pos - : pos > 0 ? rfind_impl_1(data, len, s, pos - 1, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - rfind_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return n <= len ? rfind_impl_1(data, len, s, NS_SSCRISK_CEL_OR_SPROUT::min(size_type(len - n), pos), n) - : npos - ; - } - static SPROUT_CONSTEXPR size_type - rfind_c_impl(const_iterator data, size_type len, value_type c) { - return len > 0 - ? traits_type::eq(data[len - 1], c) - ? len - 1 - : rfind_c_impl(data, len - 1, c) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_first_of_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return n && pos < len - ? traits_helper_type::is_found(traits_helper_type::find(s, n, data[pos]), s + n) - ? pos - : find_first_of_impl(data, len, s, pos + 1, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_last_of_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return traits_helper_type::is_found(traits_helper_type::find(s, n, data[len]), s + n) ? len - : len ? find_last_of_impl_1(data, len - 1, s, pos, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_last_of_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return len && n ? find_last_of_impl_1(data, len - 1 > pos ? pos : len - 1, s, pos, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_first_not_of_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return pos < len - ? !traits_helper_type::is_found(traits_helper_type::find(s, n, data[pos]), s + n) - ? pos - : find_first_not_of_impl(data, len, s, pos + 1, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_last_not_of_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return !traits_helper_type::is_found(traits_helper_type::find(s, n, data[len]), s + n) ? len - : len ? find_last_not_of_impl_1(data, len - 1, s, pos, n) - : npos - ; - } - template - static SPROUT_CONSTEXPR size_type - find_last_not_of_impl(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { - return len ? find_last_not_of_impl_1(data, len - 1 > pos ? pos : len - 1, s, pos, n) - : npos - ; - } - static SPROUT_CONSTEXPR size_type - find_last_not_of_c_impl(const_iterator data, size_type len, value_type c, size_type pos) { - return !traits_type::eq(data[len], c) ? len - : len ? find_last_not_of_c_impl(data, len - 1, c, pos) - : npos - ; - } - static SPROUT_CONSTEXPR int - compare_impl_1(int compared, size_type n1, size_type n2) { - return compared != 0 ? compared - : n1 < n2 ? -1 - : n2 < n1 ? 1 - : 0 - ; - } - template - static SPROUT_CONSTEXPR int - compare_impl(const_iterator dest, size_type pos1, size_type n1, ConstIterator s, size_type n2) { - return compare_impl_1( - traits_type::compare(dest + pos1, s, NS_SSCRISK_CEL_OR_SPROUT::min(n1, n2)), - n1, n2 - ); - } template static SPROUT_CONSTEXPR basic_string from_c_str_impl(value_type const* s, size_type n, sprout::index_tuple) { @@ -258,19 +137,19 @@ namespace sprout { #else iterator begin() SPROUT_NOEXCEPT { - return &elems[0]; + return data(); } SPROUT_CONSTEXPR const_iterator begin() const SPROUT_NOEXCEPT { - return &elems[0]; + return data(); } iterator end() SPROUT_NOEXCEPT { - return &elems[0] + size(); + return data() + size(); } SPROUT_CONSTEXPR const_iterator end() const SPROUT_NOEXCEPT { - return &elems[0] + size(); + return data() + size(); } #endif reverse_iterator @@ -301,11 +180,11 @@ namespace sprout { #else SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT { - return &elems[0]; + return data(); } SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT { - return &elems[0] + size(); + return data() + size(); } #endif SPROUT_CONSTEXPR const_reverse_iterator @@ -335,7 +214,7 @@ namespace sprout { if (n > size()) { traits_type::assign(end(), n - size(), c); } - traits_type::assign(begin() + n, max_size() - n, value_type()); + traits_type::assign(begin() + n, static_size - n, value_type()); len = n; } void @@ -344,7 +223,7 @@ namespace sprout { } void clear() { - traits_type::assign(begin(), max_size(), value_type()); + traits_type::assign(begin(), static_size, value_type()); len = 0; } SPROUT_CONSTEXPR bool @@ -362,15 +241,13 @@ namespace sprout { } reference at(size_type i) { - return i < size() - ? elems[i] + return i < size() ? elems[i] : (throw std::out_of_range("basic_string<>: index out of range"), elems[i]) ; } SPROUT_CONSTEXPR const_reference at(size_type i) const { - return i < size() - ? elems[i] + return i < size() ? elems[i] : (throw std::out_of_range("basic_string<>: index out of range"), elems[i]) ; } @@ -410,7 +287,7 @@ namespace sprout { for (size_type i = 0; i < n; ++i) { traits_type::assign(elems[i], s[i]); } - for (size_type i = n; i < max_size(); ++i) { + for (size_type i = n; i < static_size; ++i) { traits_type::assign(elems[i], value_type()); } len = n; @@ -424,7 +301,7 @@ namespace sprout { assign(size_type n, value_type c) { maxcheck(n); traits_type::assign(begin(), n, c); - traits_type::assign(begin() + n, max_size() - n, value_type()); + traits_type::assign(begin() + n, static_size - n, value_type()); len = n; return *this; } @@ -432,10 +309,10 @@ namespace sprout { basic_string& assign(Iterator first, Iterator last) { size_type n = 0; - for (; n < max_size() || first != last; ++n, ++first) { + for (; n < static_size || first != last; ++n, ++first) { traits_type::assign(elems[n], *first); } - for (size_type i = n; i < max_size(); ++i) { + for (size_type i = n; i < static_size; ++i) { traits_type::assign(elems[i], value_type()); } len = n; @@ -451,7 +328,7 @@ namespace sprout { // string operations: SPROUT_CONSTEXPR const_pointer c_str() const SPROUT_NOEXCEPT { - return &elems[0]; + return data(); } pointer data() SPROUT_NOEXCEPT { @@ -464,11 +341,11 @@ namespace sprout { template SPROUT_CONSTEXPR size_type find(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT { - return find_impl(begin(), len, str.begin(), pos, str.size()); + return sprout::string_detail::find_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type find(value_type const* s, size_type pos, size_type n) const { - return find_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type find(value_type const* s, size_type pos = 0) const { @@ -476,17 +353,16 @@ namespace sprout { } SPROUT_CONSTEXPR size_type find(value_type c, size_type pos = 0) const { - return pos < len ? find_c_impl(traits_helper_type::find(begin() + pos, len - pos, c), begin(), end()) - : npos - ; + return sprout::string_detail::find_c_impl(begin(), size(), c, pos); } + template SPROUT_CONSTEXPR size_type - rfind(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { - return rfind_impl(begin(), len, str.begin(), pos, str.size()); + rfind(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::rfind_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type rfind(value_type const* s, size_type pos, size_type n) const { - return rfind_impl(begin(), len, s, pos, n); + return sprout::string_detail::rfind_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type rfind(value_type const* s, size_type pos = npos) const { @@ -494,17 +370,16 @@ namespace sprout { } SPROUT_CONSTEXPR size_type rfind(value_type c, size_type pos = npos) const { - return len ? rfind_c_impl(begin(), len - 1 > pos ? pos + 1 : len, c) - : npos - ; + return sprout::string_detail::rfind_c_impl(begin(), size(), c, pos); } + template SPROUT_CONSTEXPR size_type - find_first_of(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT { - return find_first_of_impl(begin(), len, str.begin(), pos, str.size()); + find_first_of(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_first_of_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type find_first_of(value_type const* s, size_type pos, size_type n) const { - return find_first_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_first_of_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type find_first_of(value_type const* s, size_type pos = 0) const { @@ -514,13 +389,14 @@ namespace sprout { find_first_of(value_type c, size_type pos = 0) const { return find(c, pos); } + template SPROUT_CONSTEXPR size_type - find_last_of(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { - return find_last_of_impl(begin(), len, str.begin(), pos, str.size()); + find_last_of(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_last_of_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type find_last_of(value_type const* s, size_type pos, size_type n) const { - return find_last_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_last_of_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type find_last_of(value_type const* s, size_type pos = npos) const { @@ -530,13 +406,14 @@ namespace sprout { find_last_of(value_type c, size_type pos = npos) const { return rfind(c, pos); } + template SPROUT_CONSTEXPR size_type - find_first_not_of(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT { - return find_first_not_of_impl(begin(), len, str.begin(), pos, str.size()); + find_first_not_of(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_first_not_of_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type find_first_not_of(value_type const* s, size_type pos, size_type n) const { - return find_first_not_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_first_not_of_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type find_first_not_of(value_type const* s, size_type pos = 0) const { @@ -544,20 +421,16 @@ namespace sprout { } SPROUT_CONSTEXPR size_type find_first_not_of(value_type c, size_type pos = 0) const { - return pos < len - ? !traits_type::eq(elems[pos], c) - ? pos - : find_first_not_of(c, pos + 1) - : npos - ; + return sprout::string_detail::find_first_not_of_c_impl(begin(), size(), c, pos); } + template SPROUT_CONSTEXPR size_type - find_last_not_of(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { - return find_last_not_of_impl(begin(), len, str.begin(), pos, str.size()); + find_last_not_of(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_last_not_of_impl(begin(), size(), str.begin(), pos, str.size()); } SPROUT_CONSTEXPR size_type find_last_not_of(value_type const* s, size_type pos, size_type n) const { - return find_last_not_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_last_not_of_impl(begin(), size(), s, pos, n); } SPROUT_CONSTEXPR size_type find_last_not_of(value_type const* s, size_type pos = npos) const { @@ -565,14 +438,11 @@ namespace sprout { } SPROUT_CONSTEXPR size_type find_last_not_of(value_type c, size_type pos = npos) const { - return len ? find_last_not_of_c_impl(begin(), len - 1 > pos ? pos : len - 1, c, pos) - : npos - ; + return sprout::string_detail::find_last_not_of_c_impl(begin(), size(), c, pos); } SPROUT_CONSTEXPR basic_string substr(size_type pos = 0, size_type n = npos) const { - return !(size() < pos) - ? n == npos + return !(size() < pos) ? n == npos ? substr(pos, size() - pos) : from_c_str(c_str() + pos, n) : throw std::out_of_range("basic_string<>: index out of range") @@ -607,7 +477,7 @@ namespace sprout { SPROUT_CONSTEXPR int compare(size_type pos1, size_type n1, value_type const* s, size_type n2) const { return !(size() < pos1) - ? compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) + ? sprout::string_detail::compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) : throw std::out_of_range("basic_string<>: index out of range") ; } @@ -615,8 +485,7 @@ namespace sprout { template N)>::type> SPROUT_CONSTEXPR operator basic_string() const { return implicit_conversion_impl( - elems, - len, + elems, size(), sprout::index_range<0, N2>::make() ); } @@ -632,10 +501,11 @@ namespace sprout { } void maxcheck(size_type n) const { - if (n > max_size()) { + if (n > static_size) { throw std::out_of_range("basic_string<>: index out of range"); } } + #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION template typename std::enable_if< @@ -647,7 +517,7 @@ namespace sprout { for (size_type i = 0; i < n; ++i) { traits_type::assign(elems[i], s[i]); } - for (size_type i = n; i < max_size(); ++i) { + for (size_type i = n; i < static_size; ++i) { traits_type::assign(elems[i], value_type()); } len = n; @@ -676,7 +546,7 @@ namespace sprout { size_type >::type find(ConstIterator s, size_type pos, size_type n) const { - return find_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -692,7 +562,7 @@ namespace sprout { size_type >::type rfind(ConstIterator s, size_type pos, size_type n) const { - return rfind_impl(begin(), len, s, pos, n); + return sprout::string_detail::rfind_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -708,7 +578,7 @@ namespace sprout { size_type >::type find_first_of(ConstIterator s, size_type pos, size_type n) const { - return find_first_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_first_of_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -724,7 +594,7 @@ namespace sprout { size_type >::type find_last_of(ConstIterator s, size_type pos, size_type n) const { - return find_last_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_last_of_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -740,7 +610,7 @@ namespace sprout { size_type >::type find_first_not_of(ConstIterator s, size_type pos, size_type n) const { - return find_first_not_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_first_not_of_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -748,7 +618,7 @@ namespace sprout { size_type >::type find_first_not_of(ConstIterator s, size_type pos = 0) const { - return find_first_not_of_impl(s, pos, traits_type::length(s)); + return sprout::string_detail::find_first_not_of_impl(s, pos, traits_type::length(s)); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -756,7 +626,7 @@ namespace sprout { size_type >::type find_last_not_of(ConstIterator s, size_type pos, size_type n) const { - return find_last_not_of_impl(begin(), len, s, pos, n); + return sprout::string_detail::find_last_not_of_impl(begin(), size(), s, pos, n); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -764,7 +634,7 @@ namespace sprout { size_type >::type find_last_not_of(ConstIterator s, size_type pos = npos) const { - return find_last_not_of_impl(s, pos, traits_type::length(s)); + return sprout::string_detail::find_last_not_of_impl(s, pos, traits_type::length(s)); } template SPROUT_CONSTEXPR typename std::enable_if< @@ -789,7 +659,7 @@ namespace sprout { >::type compare(size_type pos1, size_type n1, ConstIterator s, size_type n2) const { return !(size() < pos1) - ? compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) + ? sprout::string_detail::compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) : throw std::out_of_range("basic_string<>: index out of range") ; } diff --git a/sprout/sub_array/hash.hpp b/sprout/sub_array/hash.hpp index a6fd250b..2cf34770 100644 --- a/sprout/sub_array/hash.hpp +++ b/sprout/sub_array/hash.hpp @@ -1,6 +1,8 @@ #ifndef SPROUT_SUB_ARRAY_HASH_HPP #define SPROUT_SUB_ARRAY_HASH_HPP +#include +#include #include #include #include diff --git a/sprout/tuple/tuple/hash.hpp b/sprout/tuple/tuple/hash.hpp index 4c243f56..4673cfbd 100644 --- a/sprout/tuple/tuple/hash.hpp +++ b/sprout/tuple/tuple/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_TUPLE_TUPLE_HASH_HPP #include +#include #include #include #include diff --git a/sprout/utility.hpp b/sprout/utility.hpp index c75fbc5a..7bc3f235 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #endif // #ifndef SPROUT_UTILITY_HPP diff --git a/sprout/utility/pair/hash.hpp b/sprout/utility/pair/hash.hpp index e070e16c..eab4fb23 100644 --- a/sprout/utility/pair/hash.hpp +++ b/sprout/utility/pair/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_UTILITY_PAIR_HASH_HPP #include +#include #include #include #include diff --git a/sprout/utility/string_ref.hpp b/sprout/utility/string_ref.hpp new file mode 100644 index 00000000..1f8c1382 --- /dev/null +++ b/sprout/utility/string_ref.hpp @@ -0,0 +1,12 @@ +#ifndef SPROUT_UTILITY_STRING_REF_HPP +#define SPROUT_UTILITY_STRING_REF_HPP + +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_HPP diff --git a/sprout/utility/string_ref/alias.hpp b/sprout/utility/string_ref/alias.hpp new file mode 100644 index 00000000..3fdf1274 --- /dev/null +++ b/sprout/utility/string_ref/alias.hpp @@ -0,0 +1,26 @@ +#ifndef SPROUT_UTILITY_STRING_REF_ALIAS_HPP +#define SPROUT_UTILITY_STRING_REF_ALIAS_HPP + +#include +#include + +namespace sprout { + // + // string_ref + // + typedef sprout::basic_string_ref string_ref; + // + // wstring_ref + // + typedef sprout::basic_string_ref wstring_ref; + // + // u16string_ref + // + typedef sprout::basic_string_ref u16string_ref; + // + // u32string_ref + // + typedef sprout::basic_string_ref u32string_ref; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_ALIAS_HPP diff --git a/sprout/utility/string_ref/comparison.hpp b/sprout/utility/string_ref/comparison.hpp new file mode 100644 index 00000000..386e8ccc --- /dev/null +++ b/sprout/utility/string_ref/comparison.hpp @@ -0,0 +1,109 @@ +#ifndef SPROUT_UTILITY_STRING_REF_COMPARISON_HPP +#define SPROUT_UTILITY_STRING_REF_COMPARISON_HPP + +#include +#include +#include + +namespace sprout { + // + // operator== + // operator!= + // operator< + // operator> + // operator<= + // operator>= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return lhs.compare(rhs) == 0; + } + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::basic_string_ref const& lhs, T const* rhs) { + return lhs.compare(rhs) == 0; + } + template + inline SPROUT_CONSTEXPR bool + operator==(T const* lhs, sprout::basic_string_ref const& rhs) { + return 0 == rhs.compare(lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::basic_string_ref const& lhs, T const* rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(T const* lhs, sprout::basic_string_ref const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return lhs.compare(rhs) < 0; + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::basic_string_ref const& lhs, T const* rhs) { + return lhs.compare(rhs) < 0; + } + template + inline SPROUT_CONSTEXPR bool + operator<(T const* lhs, sprout::basic_string_ref const& rhs) { + return 0 < rhs.compare(lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::basic_string_ref const& lhs, T const* rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator>(T const* lhs, sprout::basic_string_ref const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::basic_string_ref const& lhs, T const* rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<=(T const* lhs, sprout::basic_string_ref const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::basic_string_ref const& lhs, sprout::basic_string_ref const& rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::basic_string_ref const& lhs, T const* rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(T const* lhs, sprout::basic_string_ref const& rhs) { + return !(lhs < rhs); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_COMPARISON_HPP diff --git a/sprout/utility/string_ref/hash.hpp b/sprout/utility/string_ref/hash.hpp new file mode 100644 index 00000000..94a262ef --- /dev/null +++ b/sprout/utility/string_ref/hash.hpp @@ -0,0 +1,31 @@ +#ifndef SPROUT_UTILITY_STRING_REF_HASH_HPP +#define SPROUT_UTILITY_STRING_REF_HASH_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // hash_value + // + template + inline SPROUT_CONSTEXPR std::size_t + hash_value(sprout::basic_string_ref const& v) { + return sprout::hash_range(v); + } +} // namespace sprout + +namespace std { + // + // hash + // + template + struct hash > + : public sprout::hash > + {}; +} // namespace std + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_HASH_HPP diff --git a/sprout/utility/string_ref/io.hpp b/sprout/utility/string_ref/io.hpp new file mode 100644 index 00000000..6efb4c90 --- /dev/null +++ b/sprout/utility/string_ref/io.hpp @@ -0,0 +1,19 @@ +#ifndef SPROUT_UTILITY_STRING_IO_HPP +#define SPROUT_UTILITY_STRING_IO_HPP + +#include +#include +#include + +namespace sprout { + // + // operator<< + // + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::basic_string_ref const& rhs) { + return lhs << rhs.c_str(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_STRING_IO_HPP diff --git a/sprout/utility/string_ref/string_ref.hpp b/sprout/utility/string_ref/string_ref.hpp new file mode 100644 index 00000000..f7a56b30 --- /dev/null +++ b/sprout/utility/string_ref/string_ref.hpp @@ -0,0 +1,555 @@ +#ifndef SPROUT_UTILITY_STRING_REF_STRING_REF_HPP +#define SPROUT_UTILITY_STRING_REF_STRING_REF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION +# include +#endif + +namespace sprout { + // + // basic_string_ref + // + template > + class basic_string_ref { + public: + typedef T value_type; +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; +#else + typedef T const* iterator; + typedef T const* const_iterator; +#endif + typedef T const& reference; + typedef T const& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T const* pointer; + typedef T const* const_pointer; + typedef sprout::reverse_iterator reverse_iterator; + typedef sprout::reverse_iterator const_reverse_iterator; + typedef Traits traits_type; +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + private: + template + class is_string_ref_iterator + : public std::integral_constant< + bool, + std::is_same >::value + || std::is_same >::value + > + {}; + template + class is_string_ref_iterator + : public is_string_ref_iterator + {}; + template + class is_string_ref_iterator + : public is_string_ref_iterator + {}; + template + class is_string_ref_iterator + : public is_string_ref_iterator + {}; +#endif + public: + SPROUT_STATIC_CONSTEXPR size_type npos = sprout::npos; + private: + const_pointer ptr_; + size_type len_; + public: + // construct/copy/destroy: + SPROUT_CONSTEXPR basic_string_ref() + : ptr_(0), len_(0) + {} + SPROUT_CONSTEXPR basic_string_ref(basic_string_ref const& rhs) = default; + basic_string_ref& operator=(basic_string_ref const& rhs) = default; + SPROUT_CONSTEXPR basic_string_ref(const_pointer str) + : ptr_(str), len_(traits_type::length(str)) + {} + template + SPROUT_CONSTEXPR basic_string_ref(sprout::basic_string const& str) + : ptr_(str.data()), len_(str.length()) + {} + template + SPROUT_CONSTEXPR basic_string_ref(std::basic_string const& str) + : ptr_(str.data()), len_(str.length()) + {} + SPROUT_CONSTEXPR basic_string_ref(const_pointer str, size_type len) + : ptr_(str), len_(len) + {} + // iterators: +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + iterator + begin() SPROUT_NOEXCEPT { + return iterator(*this, 0); + } + SPROUT_CONSTEXPR const_iterator + begin() const SPROUT_NOEXCEPT { + return const_iterator(*this, 0); + } + iterator + end() SPROUT_NOEXCEPT { + return iterator(*this, size()); + } + SPROUT_CONSTEXPR const_iterator + end() const SPROUT_NOEXCEPT { + return const_iterator(*this, size()); + } +#else + SPROUT_CONSTEXPR const_iterator + begin() const SPROUT_NOEXCEPT { + return data(); + } + SPROUT_CONSTEXPR const_iterator + end() const SPROUT_NOEXCEPT { + return data() + size(); + } +#endif + SPROUT_CONSTEXPR const_reverse_iterator + rbegin() const SPROUT_NOEXCEPT { + return const_reverse_iterator(end()); + } + SPROUT_CONSTEXPR const_reverse_iterator + rend() const SPROUT_NOEXCEPT { + return const_reverse_iterator(begin()); + } +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + SPROUT_CONSTEXPR const_iterator + cbegin() const SPROUT_NOEXCEPT { + return const_iterator(*this, 0); + } + SPROUT_CONSTEXPR const_iterator + cend() const SPROUT_NOEXCEPT { + return const_iterator(*this, size()); + } +#else + SPROUT_CONSTEXPR const_iterator + cbegin() const SPROUT_NOEXCEPT { + return data(); + } + SPROUT_CONSTEXPR const_iterator + cend() const SPROUT_NOEXCEPT { + return data() + size(); + } +#endif + SPROUT_CONSTEXPR const_reverse_iterator + crbegin() const SPROUT_NOEXCEPT { + return const_reverse_iterator(end()); + } + SPROUT_CONSTEXPR const_reverse_iterator + crend() const SPROUT_NOEXCEPT { + return const_reverse_iterator(begin()); + } + // capacity: + SPROUT_CONSTEXPR size_type + size() const SPROUT_NOEXCEPT { + return len_; + } + SPROUT_CONSTEXPR size_type + length() const SPROUT_NOEXCEPT { + return size(); + } + SPROUT_CONSTEXPR size_type + max_size() const SPROUT_NOEXCEPT { + return size(); + } + void + clear() { + len_ = 0; + } + SPROUT_CONSTEXPR bool + empty() const SPROUT_NOEXCEPT { + return size() == 0; + } + // element access: + SPROUT_CONSTEXPR const_reference + operator[](size_type i) const { + return ptr_[i]; + } + SPROUT_CONSTEXPR const_reference + at(size_type i) const { + return i < size() ? ptr_[i] + : (throw std::out_of_range("basic_string_ref<>: index out of range"), ptr_[i]) + ; + } + SPROUT_CONSTEXPR const_reference + front() const { + return ptr_[0]; + } + SPROUT_CONSTEXPR const_reference + back() const { + return ptr_[size() - 1]; + } + // modifiers: + void + swap(basic_string_ref& other) + SPROUT_NOEXCEPT + { + sprout::swap(ptr_, other.ptr_); + sprout::swap(len_, other.len_); + } + void + remove_prefix(size_type n) { + if (n > size()) { + n = size(); + } + ptr_ += n; + len_ -= n; + } + SPROUT_CONSTEXPR basic_string_ref + remove_prefix(size_type n) { + return n > size() ? basic_string_ref(data() + size(), 0) + : basic_string_ref(data() + n, size() - n) + ; + } + void + remove_suffix(size_type n) { + if (n > size()) { + n = size(); + } + len_ -= n; + } + SPROUT_CONSTEXPR basic_string_ref + remove_suffix(size_type n) { + return n > size() ? basic_string_ref(data(), 0) + : basic_string_ref(data(), size() - n) + ; + } + // string operations: + SPROUT_CONSTEXPR const_pointer + c_str() const SPROUT_NOEXCEPT { + return data(); + } + SPROUT_CONSTEXPR const_pointer + data() const SPROUT_NOEXCEPT { + return ptr_; + } + + SPROUT_CONSTEXPR size_type + find(basic_string_ref const& str, size_type pos = 0) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + find(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::find_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + find(value_type const* s, size_type pos = 0) const { + return find(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + find(value_type c, size_type pos = 0) const { + return sprout::string_detail::find_c_impl(begin(), size(), c, pos); + } + SPROUT_CONSTEXPR size_type + rfind(basic_string_ref const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::rfind_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + rfind(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::rfind_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + rfind(value_type const* s, size_type pos = npos) const { + return rfind(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + rfind(value_type c, size_type pos = npos) const { + return sprout::string_detail::rfind_c_impl(begin(), size(), c, pos); + } + SPROUT_CONSTEXPR size_type + find_first_of(basic_string_ref const& str, size_type pos = 0) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_first_of_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + find_first_of(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::find_first_of_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + find_first_of(value_type const* s, size_type pos = 0) const { + return find_first_of(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + find_first_of(value_type c, size_type pos = 0) const { + return find(c, pos); + } + SPROUT_CONSTEXPR size_type + find_last_of(basic_string_ref const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_last_of_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + find_last_of(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::find_last_of_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + find_last_of(value_type const* s, size_type pos = npos) const { + return find_last_of(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + find_last_of(value_type c, size_type pos = npos) const { + return rfind(c, pos); + } + SPROUT_CONSTEXPR size_type + find_first_not_of(basic_string_ref const& str, size_type pos = 0) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_first_not_of_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + find_first_not_of(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::find_first_not_of_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + find_first_not_of(value_type const* s, size_type pos = 0) const { + return find_first_not_of(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + find_first_not_of(value_type c, size_type pos = 0) const { + return sprout::string_detail::find_first_not_of_c_impl(begin(), size(), c, pos); + } + SPROUT_CONSTEXPR size_type + find_last_not_of(basic_string_ref const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return sprout::string_detail::find_last_not_of_impl(begin(), size(), str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + find_last_not_of(value_type const* s, size_type pos, size_type n) const { + return sprout::string_detail::find_last_not_of_impl(begin(), size(), s, pos, n); + } + SPROUT_CONSTEXPR size_type + find_last_not_of(value_type const* s, size_type pos = npos) const { + return find_last_not_of(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + find_last_not_of(value_type c, size_type pos = npos) const { + return sprout::string_detail::find_last_not_of_c_impl(begin(), size(), c, pos); + } + SPROUT_CONSTEXPR basic_string_ref + substr(size_type pos = 0, size_type n = npos) const { + return !(size() < pos) ? n == npos + ? substr(pos, size() - pos) + : basic_string_ref(c_str() + pos, n) + : throw std::out_of_range("basic_string_ref<>: index out of range") + ; + } + SPROUT_CONSTEXPR int + compare(basic_string_ref const& str) const { + return compare(0, size(), str.begin(), str.size()); + } + SPROUT_CONSTEXPR int + compare(value_type const* s) const { + return compare(0, size(), s, traits_type::length(s)); + } + SPROUT_CONSTEXPR int + compare(size_type pos1, size_type n1, basic_string_ref const& str) const { + return compare(pos1, n1, str, 0, npos); + } + SPROUT_CONSTEXPR int + compare(size_type pos1, size_type n1, value_type const* s) const { + return compare(pos1, n1, s, traits_type::length(s)); + } + SPROUT_CONSTEXPR int + compare(size_type pos1, size_type n1, basic_string_ref const& str, size_type pos2, size_type n2) const { + return !(str.size() < pos2) + ? compare(pos1, n1, str.begin() + pos2, NS_SSCRISK_CEL_OR_SPROUT::min(n2, str.size() - pos2)) + : throw std::out_of_range("basic_string_ref<>: index out of range") + ; + } + SPROUT_CONSTEXPR int + compare(size_type pos1, size_type n1, value_type const* s, size_type n2) const { + return !(size() < pos1) + ? sprout::string_detail::compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) + : throw std::out_of_range("basic_string_ref<>: index out of range") + ; + } + SPROUT_CONSTEXPR bool + starts_with(value_type c) const { + return !empty() && traits_type::eq(c, front()); + } + SPROUT_CONSTEXPR bool + starts_with(basic_string_ref const& str) const { + return size() >= str.size() && traits_type::compare(data(), str.data(), str.size()) == 0; + } + SPROUT_CONSTEXPR bool + ends_with(value_type c) const { + return !empty() && traits_type::eq(c, back()); + } + SPROUT_CONSTEXPR bool + ends_with(basic_string_ref const& str) const { + return size() >= str.size() && traits_type::compare(data() + size() - str.size(), str.data(), str.size()) == 0; + } + // others: +#if SPROUT_USE_EXPLICIT_CONVERSION_OPERATORS + template + explicit operator std::basic_string() const { + return std::basic_string(data(), size()); + } +#endif + pointer + c_array() SPROUT_NOEXCEPT { + return data(); + } + void + rangecheck(size_type i) const { + if (i >= size()) { + throw std::out_of_range("basic_string_ref<>: index out of range"); + } + } + void + maxcheck(size_type n) const { + rangecheck(n); + } + +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::find_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find(ConstIterator s, size_type pos = 0) const { + return find(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + rfind(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::rfind_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + rfind(ConstIterator s, size_type pos = npos) const { + return rfind(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_first_of(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::find_first_of_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_first_of(ConstIterator s, size_type pos = 0) const { + return find_first_of(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_last_of(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::find_last_of_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_last_of(ConstIterator s, size_type pos = 0) const { + return find_last_of(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_first_not_of(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::find_first_not_of_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_first_not_of(ConstIterator s, size_type pos = 0) const { + return sprout::string_detail::find_first_not_of_impl(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_last_not_of(ConstIterator s, size_type pos, size_type n) const { + return sprout::string_detail::find_last_not_of_impl(begin(), size(), s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + size_type + >::type + find_last_not_of(ConstIterator s, size_type pos = npos) const { + return sprout::string_detail::find_last_not_of_impl(s, pos, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + int + >::type + compare(ConstIterator s) const { + return compare(0, size(), s, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + int + >::type + compare(size_type pos1, size_type n1, ConstIterator s) const { + return compare(pos1, n1, s, traits_type::length(s)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + is_string_ref_iterator::value, + int + >::type + compare(size_type pos1, size_type n1, ConstIterator s, size_type n2) const { + return !(size() < pos1) + ? sprout::string_detail::compare_impl(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT::min(n1, size() - pos1), s, n2) + : throw std::out_of_range("basic_string_ref<>: index out of range") + ; + } +#endif + }; + template + SPROUT_CONSTEXPR_OR_CONST typename sprout::basic_string_ref::size_type sprout::basic_string_ref::npos; + + // + // swap + // + template + inline void + swap(sprout::basic_string_ref& lhs, sprout::basic_string_ref& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_STRING_REF_HPP diff --git a/sprout/utility/string_ref/type_traits.hpp b/sprout/utility/string_ref/type_traits.hpp new file mode 100644 index 00000000..20f1b952 --- /dev/null +++ b/sprout/utility/string_ref/type_traits.hpp @@ -0,0 +1,79 @@ +#ifndef SPROUT_UTILITY_STRING_REF_TYPE_TRAITS_HPP +#define SPROUT_UTILITY_STRING_REF_TYPE_TRAITS_HPP + +#include +#include +#include + +namespace sprout { + // + // is_basic_string_ref + // + template + struct is_basic_string_ref + : public std::false_type + {}; + template + struct is_basic_string_ref + : public sprout::is_basic_string_ref + {}; + template + struct is_basic_string_ref + : public sprout::is_basic_string_ref + {}; + template + struct is_basic_string_ref > + : public std::true_type + {}; + + // + // is_string_ref_of + // + template + struct is_string_ref_of + : public std::false_type + {}; + template + struct is_string_ref_of + : public sprout::is_string_ref_of + {}; + template + struct is_string_ref_of + : public sprout::is_string_ref_of + {}; + template + struct is_string_ref_of, Elem> + : public std::true_type + {}; + + // + // is_string_ref + // + template + struct is_string_ref + : public sprout::is_string_ref_of + {}; + // + // is_wstring_ref + // + template + struct is_wstring_ref + : public sprout::is_string_ref_of + {}; + // + // is_u16string_ref + // + template + struct is_u16string_ref + : public sprout::is_string_ref_of + {}; + // + // is_u32string_ref + // + template + struct is_u32string_ref + : public sprout::is_string_ref_of + {}; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_STRING_REF_TYPE_TRAITS_HPP diff --git a/sprout/utility/value_holder/hash.hpp b/sprout/utility/value_holder/hash.hpp index 2ea7d574..2c737e14 100644 --- a/sprout/utility/value_holder/hash.hpp +++ b/sprout/utility/value_holder/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_UTILITY_VALUE_HOLDER_HASH_HPP #include +#include #include #include #include diff --git a/sprout/uuid/detail/table.hpp b/sprout/uuid/detail/table.hpp index 622c415e..6d4470bb 100644 --- a/sprout/uuid/detail/table.hpp +++ b/sprout/uuid/detail/table.hpp @@ -38,7 +38,7 @@ namespace sprout { ; SPROUT_CONSTEXPR_OR_CONST wchar_t sprout::uuids::detail::digits::dash; -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> struct digits { public: diff --git a/sprout/uuid/hash.hpp b/sprout/uuid/hash.hpp index 1e515c66..136ae785 100644 --- a/sprout/uuid/hash.hpp +++ b/sprout/uuid/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_UUID_HASH_HPP #include +#include #include #include #include diff --git a/sprout/uuid/uuid.hpp b/sprout/uuid/uuid.hpp index eb005363..55ca38b9 100644 --- a/sprout/uuid/uuid.hpp +++ b/sprout/uuid/uuid.hpp @@ -34,8 +34,8 @@ namespace sprout { public: typedef std::uint8_t value_type; #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - typedef sprout::index_iterator iterator; - typedef sprout::index_iterator const_iterator; + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; #else typedef std::uint8_t* iterator; typedef std::uint8_t const* const_iterator; diff --git a/sprout/variant/hash.hpp b/sprout/variant/hash.hpp index 8aa5d325..94ea0ca1 100644 --- a/sprout/variant/hash.hpp +++ b/sprout/variant/hash.hpp @@ -2,6 +2,7 @@ #define SPROUT_VARIANT_HASH_HPP #include +#include #include #include #include diff --git a/sprout/weed/detail/bdigits.hpp b/sprout/weed/detail/bdigits.hpp index f142ad65..3e8668a2 100644 --- a/sprout/weed/detail/bdigits.hpp +++ b/sprout/weed/detail/bdigits.hpp @@ -37,7 +37,7 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(sprout::to_string(L"01")) ; -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> struct bdigits { public: diff --git a/sprout/weed/detail/digits.hpp b/sprout/weed/detail/digits.hpp index b398b2e3..7c1b5661 100644 --- a/sprout/weed/detail/digits.hpp +++ b/sprout/weed/detail/digits.hpp @@ -37,7 +37,7 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(sprout::to_string(L"0123456789")) ; -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> struct digits { public: diff --git a/sprout/weed/detail/odigits.hpp b/sprout/weed/detail/odigits.hpp index 4fdeba25..37595473 100644 --- a/sprout/weed/detail/odigits.hpp +++ b/sprout/weed/detail/odigits.hpp @@ -37,7 +37,7 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(sprout::to_string(L"01234567")) ; -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> struct odigits { public: diff --git a/sprout/weed/detail/xdigits.hpp b/sprout/weed/detail/xdigits.hpp index 40c4d69d..679e0f56 100644 --- a/sprout/weed/detail/xdigits.hpp +++ b/sprout/weed/detail/xdigits.hpp @@ -37,7 +37,7 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(sprout::to_string(L"0123456789abcdefABCDEF")) ; -#ifndef SPROUT_NO_UNICODE_LITERALS +#if SPROUT_USE_UNICODE_LITERALS template<> struct xdigits { public: diff --git a/testspr/sprout.cpp b/testspr/sprout.cpp index 4caf18a2..a271590f 100644 --- a/testspr/sprout.cpp +++ b/testspr/sprout.cpp @@ -14,6 +14,7 @@ #include "../libs/variant/test/variant.cpp" #include "../libs/algorithm/test/algorithm.cpp" #include "../libs/random/test/random.cpp" +#include "../libs/utility/string_ref/test/string_ref.cpp" #include "../libs/cstring/test/cstring.cpp" #ifdef TESTSPR_CPP_INCLUDE_DISABLE_TESTSPR_SPROUT_HPP @@ -30,6 +31,7 @@ namespace testspr { testspr::variant_test(); testspr::algorithm_test(); testspr::random_test(); + testspr::string_ref_test(); testspr::cstring_test(); } } // namespace testspr