diff --git a/libs/string/test/string.cpp b/libs/string/test/string.cpp index 1861ca17..06f22537 100644 --- a/libs/string/test/string.cpp +++ b/libs/string/test/string.cpp @@ -25,6 +25,60 @@ namespace testspr { TESTSPR_BOTH_ASSERT((std::is_same const>::value)); TESTSPR_BOTH_ASSERT((std::is_same const>::value)); + // constructor + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(); + TESTSPR_BOTH_ASSERT(s1.size() == 0); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = str1; + TESTSPR_BOTH_ASSERT(s1 == str1); + } + { + SPROUT_STATIC_CONSTEXPR std::decay::type s1 = str2; + TESTSPR_BOTH_ASSERT(s1 == str2); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = std::decay::type(str1, 6); + TESTSPR_BOTH_ASSERT(s1 == "1234"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = std::decay::type(str1, 0, 6); + TESTSPR_BOTH_ASSERT(s1 == "foobar"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = std::decay::type(str2, 4); + TESTSPR_BOTH_ASSERT(s1 == "hoge"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = std::decay::type(str2, 0, 4); + TESTSPR_BOTH_ASSERT(s1 == "hoge"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(cstr); + TESTSPR_BOTH_ASSERT(s1 == cstr); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(cstr, 6); + TESTSPR_BOTH_ASSERT(s1 == "foobar"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(static_cast(cstr)); + TESTSPR_BOTH_ASSERT(s1 == cstr); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(static_cast(cstr), 6); + TESTSPR_BOTH_ASSERT(s1 == "foobar"); + } + { + SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(cstr, cstr + 6); + TESTSPR_BOTH_ASSERT(s1 == "foobar"); + } + { + auto s1 = sprout::string_t<10>::type({'f', 'o', 'o', 'b', 'a', 'r'}); + TESTSPR_ASSERT(s1 == "foobar"); + } + // begin TESTSPR_BOTH_ASSERT(cstr[0] == *str1.begin()); diff --git a/sprout/algorithm/equal_range.hpp b/sprout/algorithm/equal_range.hpp index 85a527dd..fc891363 100644 --- a/sprout/algorithm/equal_range.hpp +++ b/sprout/algorithm/equal_range.hpp @@ -26,10 +26,10 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair equal_range(ForwardIterator first, ForwardIterator last, T const& value, Compare comp) { - return sprout::pair{ + return sprout::pair( sprout::lower_bound(first, last, value, comp), sprout::upper_bound(first, last, value, comp) - }; + ); } template diff --git a/sprout/algorithm/mismatch.hpp b/sprout/algorithm/mismatch.hpp index 0a4d402b..d7860452 100644 --- a/sprout/algorithm/mismatch.hpp +++ b/sprout/algorithm/mismatch.hpp @@ -24,9 +24,9 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair mismatch_impl_check(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) { - return sprout::pair{ + return sprout::pair( found, sprout::next(first2, sprout::distance(first1, found)) - }; + ); } template @@ -59,7 +59,7 @@ namespace sprout { std::random_access_iterator_tag* ) { - return first1 == last1 ? sprout::pair{first1, first2} + return first1 == last1 ? sprout::pair(first1, first2) : sprout::detail::mismatch_impl_check( first1, first2, sprout::detail::mismatch_impl_ra( @@ -190,7 +190,7 @@ namespace sprout { std::random_access_iterator_tag* ) { - return first1 == last1 || first2 == last2 ? sprout::pair{first1, first2} + return first1 == last1 || first2 == last2 ? sprout::pair(first1, first2) : sprout::detail::mismatch_impl_check( first1, first2, sprout::detail::mismatch2_impl_ra( diff --git a/sprout/cstdlib/str_to_float.hpp b/sprout/cstdlib/str_to_float.hpp index 08d62a83..1460d236 100644 --- a/sprout/cstdlib/str_to_float.hpp +++ b/sprout/cstdlib/str_to_float.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/sprout/detail/math/float.hpp b/sprout/detail/math/float.hpp index 067bd0bc..c5d9673c 100644 --- a/sprout/detail/math/float.hpp +++ b/sprout/detail/math/float.hpp @@ -34,7 +34,7 @@ namespace sprout { // // float_exponent10 // - // !!! + // !!! TODO: O(logN) template inline SPROUT_CONSTEXPR int float_exponent10_positive(FloatType val) { diff --git a/sprout/io.hpp b/sprout/io.hpp index 9ebd981b..45a3cb81 100644 --- a/sprout/io.hpp +++ b/sprout/io.hpp @@ -710,9 +710,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR auto eval(sprout::io::format_holder const& holder) - -> decltype(sprout::basic_string{{static_cast(holder.value())}, 1}) + -> decltype(sprout::detail::string_construct_access::raw_construct(1, static_cast(holder.value()))) { - return sprout::basic_string{{static_cast(holder.value())}, 1}; + return sprout::detail::string_construct_access::raw_construct(1, static_cast(holder.value())); } template< typename Elem, std::size_t N, typename T, @@ -753,17 +753,16 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string output_impl_1(sprout::index_tuple, sprout::array const& sizes, Args const&... args) { - return sprout::basic_string{ - { - sprout::io::detail::get_param( - sprout::range::lower_bound(sizes, static_cast(Indexes + 1)), - sizes, - Indexes, - args... - )... - }, - NS_SSCRISK_CEL_OR_SPROUT::min(sizes.back(), N) - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + NS_SSCRISK_CEL_OR_SPROUT::min(sizes.back(), N), + sprout::io::detail::get_param( + sprout::range::lower_bound(sizes, static_cast(Indexes + 1)), + sizes, + Indexes, + args... + )... + ); } template inline SPROUT_CONSTEXPR sprout::basic_string diff --git a/sprout/logic/tribool/hash.hpp b/sprout/logic/tribool/hash.hpp index 43d183b5..0ac2494b 100644 --- a/sprout/logic/tribool/hash.hpp +++ b/sprout/logic/tribool/hash.hpp @@ -10,18 +10,32 @@ #include #include +#include #include #include #include namespace sprout { // - // hash_value + // hash_value_traits // - inline SPROUT_CONSTEXPR std::size_t - hash_value(sprout::logic::indeterminate_keyword_t) { - return sprout::logic::tribool::indeterminate_value; - } + template<> + struct hash_value_traits { + public: + static SPROUT_CONSTEXPR std::size_t + hash_value(sprout::logic::indeterminate_keyword_t) { + return sprout::logic::tribool::indeterminate_value; + } + }; + template<> + struct hash_value_traits::type> { + public: + static SPROUT_CONSTEXPR std::size_t + hash_value(sprout::logic::indeterminate_keyword_t) { + return sprout::logic::tribool::indeterminate_value; + } + }; + namespace logic { // // hash_value diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp index abf32eae..b664f835 100644 --- a/sprout/optional/optional.hpp +++ b/sprout/optional/optional.hpp @@ -118,10 +118,11 @@ namespace sprout { : init(true) , val(v) {} - SPROUT_CONSTEXPR optional(T&& v) - : init(true) - , val(sprout::move(v)) - {} + // !!! for T const& +// SPROUT_CONSTEXPR optional(T&& v) +// : init(true) +// , val(sprout::move(v)) +// {} template< typename... Args, typename = typename std::enable_if::value>::type @@ -142,10 +143,11 @@ namespace sprout { : init(cond) , val(cond ? holder_type(v) : holder_type()) {} - SPROUT_CONSTEXPR optional(bool cond, T&& v) - : init(cond) - , val(cond ? holder_type(sprout::move(v)) : holder_type()) - {} + // !!! for T const& +// SPROUT_CONSTEXPR optional(bool cond, T&& v) +// : init(cond) +// , val(cond ? holder_type(sprout::move(v)) : holder_type()) +// {} template explicit SPROUT_CONSTEXPR optional(optional const& v) : init(v.is_initialized()) diff --git a/sprout/rational/rational.hpp b/sprout/rational/rational.hpp index 093dfb9a..86b78332 100644 --- a/sprout/rational/rational.hpp +++ b/sprout/rational/rational.hpp @@ -24,7 +24,8 @@ namespace sprout { struct rational_private_constructor_tag {}; template - inline SPROUT_CONSTEXPR sprout::rational make_rational( + inline SPROUT_CONSTEXPR sprout::rational + make_rational( typename sprout::detail::call_traits::param_type n, typename sprout::detail::call_traits::param_type d, sprout::detail::rational_private_constructor_tag diff --git a/sprout/string/concat.hpp b/sprout/string/concat.hpp index 4db11e39..bb82484d 100644 --- a/sprout/string/concat.hpp +++ b/sprout/string/concat.hpp @@ -25,15 +25,14 @@ namespace sprout { sprout::index_tuple ) { - return sprout::basic_string{ - { - (Indexes < lsize ? lhs[Indexes] - : Indexes < lsize + 1 ? rhs - : T() - )... - }, - lsize + 1 - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + lsize + 1, + (Indexes < lsize ? lhs[Indexes] + : Indexes < lsize + 1 ? rhs + : T() + )... + ); } template inline SPROUT_CONSTEXPR sprout::basic_string @@ -43,15 +42,14 @@ namespace sprout { sprout::index_tuple ) { - return sprout::basic_string{ - { - (Indexes < 1 ? lhs - : Indexes < 1 + rsize ? rhs[Indexes - 1] - : T() - )... - }, - 1 + rsize - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + 1 + rsize, + (Indexes < 1 ? lhs + : Indexes < 1 + rsize ? rhs[Indexes - 1] + : T() + )... + ); } template inline SPROUT_CONSTEXPR sprout::basic_string @@ -61,15 +59,14 @@ namespace sprout { sprout::index_tuple ) { - return sprout::basic_string{ - { - (Indexes < lsize ? lhs[Indexes] - : Indexes < lsize + rsize ? rhs[Indexes - lsize] - : T() - )... - }, - lsize + rsize - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + lsize + rsize, + (Indexes < lsize ? lhs[Indexes] + : Indexes < lsize + rsize ? rhs[Indexes - lsize] + : T() + )... + ); } template inline SPROUT_CONSTEXPR sprout::basic_string @@ -79,15 +76,14 @@ namespace sprout { sprout::index_tuple ) { - return sprout::basic_string{ - { - (Indexes < lsize ? lhs[Indexes] - : Indexes < lsize + rsize ? rhs[Indexes - lsize] - : T() - )... - }, - lsize + rsize - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + lsize + rsize, + (Indexes < lsize ? lhs[Indexes] + : Indexes < lsize + rsize ? rhs[Indexes - lsize] + : T() + )... + ); } template inline SPROUT_CONSTEXPR sprout::basic_string @@ -97,15 +93,14 @@ namespace sprout { sprout::index_tuple ) { - return sprout::basic_string{ - { - (Indexes < lsize ? lhs[Indexes] - : Indexes < lsize + rsize ? rhs[Indexes - lsize] - : T() - )... - }, - lsize + rsize - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + lsize + rsize, + (Indexes < lsize ? lhs[Indexes] + : Indexes < lsize + rsize ? rhs[Indexes - lsize] + : T() + )... + ); } } // namespace detail diff --git a/sprout/string/float_to_string.hpp b/sprout/string/float_to_string.hpp index 3130372e..c62d944e 100644 --- a/sprout/string/float_to_string.hpp +++ b/sprout/string/float_to_string.hpp @@ -44,31 +44,27 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl(FloatType val, bool negative, int digits, int v, sprout::index_tuple) { - typedef sprout::basic_string::value> type; + typedef sprout::detail::string_construct_access::value> access_type; return negative - ? type{ - { - static_cast('-'), - (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) - : Indexes == digits ? static_cast('.') - : Indexes < digits + 1 + sprout::detail::decimal_places_length - ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) - : Elem() - )... - }, - static_cast(digits + 2 + sprout::detail::decimal_places_length) - } - : type{ - { - (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) - : Indexes == digits ? static_cast('.') - : Indexes < digits + 1 + sprout::detail::decimal_places_length - ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) - : Elem() - )... - }, - static_cast(digits + 1 + sprout::detail::decimal_places_length) - } + ? access_type::raw_construct( + static_cast(digits + 2 + sprout::detail::decimal_places_length), + static_cast('-'), + (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) + : Indexes == digits ? static_cast('.') + : Indexes < digits + 1 + sprout::detail::decimal_places_length + ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) + : Elem() + )... + ) + : access_type::raw_construct( + static_cast(digits + 1 + sprout::detail::decimal_places_length), + (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) + : Indexes == digits ? static_cast('.') + : Indexes < digits + 1 + sprout::detail::decimal_places_length + ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) + : Elem() + )... + ) ; } template @@ -90,13 +86,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val) { - typedef sprout::basic_string::value> type; + typedef sprout::detail::string_construct_access::value> access_type; return sprout::math::isinf(val) ? sprout::math::signbit(val) - ? type{{static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')}, 4} - : type{{static_cast('i'), static_cast('n'), static_cast('f')}, 3} + ? access_type::raw_construct(4, static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')) + : access_type::raw_construct(3, static_cast('i'), static_cast('n'), static_cast('f')) : sprout::math::isnan(val) ? sprout::math::signbit(val) - ? type{{static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')}, 4} - : type{{static_cast('n'), static_cast('a'), static_cast('n')}, 3} + ? access_type::raw_construct(4, static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')) + : access_type::raw_construct(3, static_cast('n'), static_cast('a'), static_cast('n')) : sprout::detail::float_to_string( sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length), sprout::math::signbit(val), @@ -130,39 +126,35 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val, bool negative, int exponent10, int e10_digits, sprout::index_tuple) { - typedef sprout::basic_string::value> type; + typedef sprout::detail::string_construct_access::value> access_type; return negative - ? type{ - { - static_cast('-'), - (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) - : Indexes == 1 ? static_cast('.') - : Indexes < 2 + sprout::detail::decimal_places_length - ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) - : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') - : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') - : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits - ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) - : Elem() - )... - }, - static_cast(5 + sprout::detail::decimal_places_length + e10_digits) - } - : type{ - { - (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) - : Indexes == 1 ? static_cast('.') - : Indexes < 2 + sprout::detail::decimal_places_length - ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) - : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') - : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') - : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits - ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) - : Elem() - )... - }, - static_cast(4 + sprout::detail::decimal_places_length + e10_digits) - } + ? access_type::raw_construct( + static_cast(5 + sprout::detail::decimal_places_length + e10_digits), + static_cast('-'), + (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) + : Indexes == 1 ? static_cast('.') + : Indexes < 2 + sprout::detail::decimal_places_length + ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) + : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') + : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') + : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits + ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) + : Elem() + )... + ) + : access_type::raw_construct( + static_cast(4 + sprout::detail::decimal_places_length + e10_digits), + (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) + : Indexes == 1 ? static_cast('.') + : Indexes < 2 + sprout::detail::decimal_places_length + ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) + : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') + : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') + : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits + ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) + : Elem() + )... + ) ; } } // namespace detail @@ -176,13 +168,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val) { - typedef sprout::basic_string::value> type; + typedef sprout::detail::string_construct_access::value> access_type; return sprout::math::isinf(val) ? sprout::math::signbit(val) - ? type{{static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')}, 4} - : type{{static_cast('i'), static_cast('n'), static_cast('f')}, 3} + ? access_type::raw_construct(4, static_cast('-'), static_cast('i'), static_cast('n'), static_cast('f')) + : access_type::raw_construct(3, static_cast('i'), static_cast('n'), static_cast('f')) : sprout::math::isnan(val) ? sprout::math::signbit(val) - ? type{{static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')}, 4} - : type{{static_cast('n'), static_cast('a'), static_cast('n')}, 3} + ? access_type::raw_construct(4, static_cast('-'), static_cast('n'), static_cast('a'), static_cast('n')) + : access_type::raw_construct(3, static_cast('n'), static_cast('a'), static_cast('n')) : sprout::detail::float_to_string_exp( sprout::detail::float_round_at( (val < 0 ? -val : val) / sprout::detail::float_pow10(sprout::detail::float_exponent10(val)), diff --git a/sprout/string/int_to_string.hpp b/sprout/string/int_to_string.hpp index a3be6aaf..a9c2d3e2 100644 --- a/sprout/string/int_to_string.hpp +++ b/sprout/string/int_to_string.hpp @@ -38,23 +38,20 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> int_to_string(IntType val, int digits, sprout::index_tuple) { - return val < 0 ? sprout::basic_string::value>{ - { - static_cast('-'), - (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) - : Elem() - )... - }, - static_cast(digits + 1) - } - : sprout::basic_string::value>{ - { - (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) - : Elem() - )... - }, - static_cast(digits) - } + typedef sprout::detail::string_construct_access::value> access_type; + return val < 0 ? access_type::raw_construct( + static_cast(digits + 1), + static_cast('-'), + (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) + : Elem() + )... + ) + : access_type::raw_construct( + static_cast(digits), + (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) + : Elem() + )... + ) ; } template< @@ -64,14 +61,13 @@ namespace sprout { > inline SPROUT_CONSTEXPR sprout::basic_string::value> int_to_string(IntType val, int digits, sprout::index_tuple) { - return sprout::basic_string::value>{ - { - (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) - : Elem() - )... - }, - static_cast(digits) - }; + typedef sprout::detail::string_construct_access::value> access_type; + return access_type::raw_construct( + static_cast(digits), + (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(val, digits - 1 - Indexes)) + : Elem() + )... + ); } } // namespace detail diff --git a/sprout/string/io.hpp b/sprout/string/io.hpp index e4039247..584c9584 100644 --- a/sprout/string/io.hpp +++ b/sprout/string/io.hpp @@ -58,10 +58,7 @@ namespace sprout { state |= std::ios_base::failbit; } lhs.setstate(state); - rhs.len = current; - for (; current != rhs.max_size(); ++current) { - rhs[current] = T(); - } + rhs.resize(current); return lhs; } template diff --git a/sprout/string/make_string.hpp b/sprout/string/make_string.hpp index 27d191b6..90c356f2 100644 --- a/sprout/string/make_string.hpp +++ b/sprout/string/make_string.hpp @@ -34,7 +34,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string::type, 0> make_string_as() { - return sprout::basic_string::type, 0>{}; + return sprout::basic_string::type, 0>(); } template inline SPROUT_CONSTEXPR sprout::basic_string::type, sizeof...(Types)> diff --git a/sprout/string/shrink.hpp b/sprout/string/shrink.hpp index 9b65b21b..b897a02d 100644 --- a/sprout/string/shrink.hpp +++ b/sprout/string/shrink.hpp @@ -27,14 +27,15 @@ namespace sprout { private: typedef sprout::value_holder holder_type; private: - template + template static SPROUT_CONSTEXPR sprout::basic_string implicit_conversion_impl( - T const(& elems)[M], std::size_t len, + string_type const& str, std::size_t len, sprout::index_tuple ) { - return sprout::basic_string{{(Indexes < M - 1 ? elems[Indexes] : T())...}, len}; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct(len, (Indexes < N ? str[Indexes] : T())...); } private: holder_type holder_; @@ -50,8 +51,8 @@ namespace sprout { template SPROUT_CONSTEXPR operator sprout::basic_string() const { return implicit_conversion_impl( - holder_.get().elems, - NS_SSCRISK_CEL_OR_SPROUT::min(N2, holder_.get().len), + holder_.get(), + NS_SSCRISK_CEL_OR_SPROUT::min(N2, holder_.get().size()), sprout::make_index_tuple<(N < N2 ? N : N2)>::make() ); } diff --git a/sprout/string/string.hpp b/sprout/string/string.hpp index 76f7b866..aa1815b6 100644 --- a/sprout/string/string.hpp +++ b/sprout/string/string.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,31 +34,105 @@ #endif namespace sprout { + namespace detail { + struct string_raw_construct_t {}; + struct string_from_c_str_construct_t {}; + + template > + class string_construct_access; + + template + class basic_string_impl { + friend class sprout::detail::string_construct_access; + public: + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef T const* const_pointer; + typedef Traits traits_type; + protected: + value_type elems[N + 1]; + size_type len; + protected: + SPROUT_CONSTEXPR basic_string_impl() + : elems{}, len() + {} + SPROUT_CONSTEXPR basic_string_impl(basic_string_impl const&) = default; + SPROUT_CONSTEXPR basic_string_impl(basic_string_impl&&) SPROUT_NOEXCEPT = default; + template + SPROUT_CONSTEXPR basic_string_impl( + sprout::index_tuple, + String const& str, size_type pos, size_type n + ) + : elems{ + (sprout::math::less(Indexes, n) ? str[Indexes + pos] + : value_type() + )... + } + , len(n) + {} + template + SPROUT_CONSTEXPR basic_string_impl( + sprout::index_tuple, + sprout::detail::string_from_c_str_construct_t, String const& str, size_type pos, size_type n + ) + : elems{ + (sprout::math::less(Indexes, n) ? str[Indexes + pos] + : value_type() + )... + } + , len(!(N < n) ? n + : throw std::out_of_range("basic_string<>: index out of range") + ) + {} + template + SPROUT_CONSTEXPR basic_string_impl( + sprout::index_tuple, + sprout::detail::string_raw_construct_t, size_type n, Args&&... args + ) + : elems{ + (sprout::math::less(Indexes, n) ? sprout::forward(args) + : value_type() + )... + } + , len(n) + {} + }; + } // namespace detail + // // basic_string // template > - class basic_string { - 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* iterator; - typedef T const* const_iterator; -#endif - typedef T& reference; - typedef T const& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef T* 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 + class basic_string + : private sprout::detail::basic_string_impl + { + friend class sprout::detail::string_construct_access; private: + typedef sprout::detail::basic_string_impl impl_type; + public: + typedef typename impl_type::value_type value_type; + typedef typename impl_type::reference reference; + typedef typename impl_type::const_reference const_reference; + typedef typename impl_type::size_type size_type; + typedef typename impl_type::difference_type difference_type; + typedef typename impl_type::pointer pointer; + typedef typename impl_type::const_pointer const_pointer; + typedef typename impl_type::traits_type traits_type; +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + typedef sprout::index_iterator iterator; + typedef sprout::index_iterator const_iterator; +#else + typedef T* iterator; + typedef T const* const_iterator; +#endif + typedef sprout::reverse_iterator reverse_iterator; + typedef sprout::reverse_iterator const_reverse_iterator; + private: +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION template class is_string_iterator : public std::false_type @@ -85,36 +161,99 @@ namespace sprout { public: SPROUT_STATIC_CONSTEXPR size_type npos = sprout::npos_t::get::value; SPROUT_STATIC_CONSTEXPR size_type static_size = N; - private: - template - static SPROUT_CONSTEXPR basic_string - from_c_str_impl(value_type const* s, size_type n, sprout::index_tuple) { - return basic_string{{(Indexes < n ? s[Indexes] : T())...}, n}; - } - template - static SPROUT_CONSTEXPR basic_string - implicit_conversion_impl(T const(& elems)[M], size_type len, sprout::index_tuple) { - return sprout::basic_string{{(Indexes < M - 1 ? elems[Indexes] : T())...}, len}; - } public: static SPROUT_CONSTEXPR basic_string from_c_str(T const* s, size_type n) { - return !(N < n) - ? from_c_str_impl(s, n, sprout::make_index_tuple::make()) - : throw std::out_of_range("basic_string<>: index out of range") - ; + return basic_string(s, n); } static SPROUT_CONSTEXPR basic_string from_c_str(T const* s) { - return from_c_str(s, traits_type::length(s)); + return basic_string(s); } static SPROUT_CONSTEXPR basic_string from_c_str(std::basic_string const& s) { return from_c_str(s.data(), s.size()); } - public: - value_type elems[static_size + 1]; - size_type len; + private: + using impl_type::elems; + using impl_type::len; + private: + template::type> + SPROUT_CONSTEXPR basic_string(sprout::detail::string_raw_construct_t, size_type n, Args&&... args) + : impl_type( + sprout::index_pack::make(), + sprout::detail::string_raw_construct_t(), n, sprout::forward(args)... + ) + {} public: // construct/copy/destroy: - template + SPROUT_CONSTEXPR basic_string() = default; + SPROUT_CONSTEXPR basic_string(basic_string const&) = default; + template::type> + SPROUT_CONSTEXPR basic_string(basic_string const& str) + : impl_type( + sprout::make_index_tuple::make(), + str, 0, str.size() + ) + {} + SPROUT_CONSTEXPR basic_string(basic_string const& str, size_type pos, size_type n = npos) + : impl_type( + sprout::make_index_tuple::make(), + str, pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos) + ) + {} + template::type> + SPROUT_CONSTEXPR basic_string(basic_string const& str, size_type pos, size_type n = npos) + : impl_type( + sprout::make_index_tuple::make(), + str, pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos) + ) + {} + template::type> + SPROUT_CONSTEXPR basic_string(T const(& arr)[N2]) + : impl_type( + sprout::make_index_tuple::make(), + arr, 0, sprout::char_traits_helper::traits_type>::length(arr, N2 - 1) + ) + {} + template::type> + SPROUT_CONSTEXPR basic_string(T const(& arr)[N2], size_type n) + : impl_type( + sprout::make_index_tuple::make(), + arr, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, sprout::char_traits_helper::traits_type>::length(arr, N2 - 1)) + ) + {} + SPROUT_CONSTEXPR basic_string(value_type const* s) + : impl_type( + sprout::make_index_tuple::make(), + sprout::detail::string_from_c_str_construct_t(), s, 0, traits_type::length(s) + ) + {} + SPROUT_CONSTEXPR basic_string(value_type const* s, size_type n) + : impl_type( + sprout::make_index_tuple::make(), + sprout::detail::string_from_c_str_construct_t(), s, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, traits_type::length(s)) + ) + {} + // !!! +// template +// SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last); + template + SPROUT_CONSTEXPR basic_string(RandomAccessIterator first, RandomAccessIterator last) + : impl_type( + sprout::make_index_tuple::make(), + sprout::detail::string_from_c_str_construct_t(), first, 0, sprout::distance(first, last) + ) + {} + basic_string(std::initializer_list il) + : impl_type( + sprout::make_index_tuple::make(), + sprout::detail::string_from_c_str_construct_t(), il.begin(), 0, il.size() + ) + {} + + basic_string& + operator=(basic_string const& rhs) { + return assign(rhs); + } + template::type> basic_string& operator=(basic_string const& rhs) { return assign(rhs); @@ -493,13 +632,6 @@ namespace sprout { ; } // others: - template N)>::type> - SPROUT_CONSTEXPR operator basic_string() const { - return implicit_conversion_impl( - elems, size(), - sprout::make_index_tuple::make() - ); - } template SPROUT_EXPLICIT_CONVERSION operator std::basic_string() const { return std::basic_string(data(), size()); @@ -697,6 +829,16 @@ namespace sprout { } namespace detail { + template + class string_construct_access { + public: + template + static SPROUT_CONSTEXPR sprout::basic_string + raw_construct(typename sprout::basic_string::size_type n, Args&&... args) { + return sprout::basic_string(sprout::detail::string_raw_construct_t(), n, sprout::forward(args)...); + } + }; + template struct make_construct_impl; @@ -710,11 +852,6 @@ namespace sprout { length_impl(sprout::array const& arr) { return sprout::distance(arr.begin(), sprout::find(arr.begin(), arr.end(), T())); } - template - static SPROUT_CONSTEXPR copied_type - make_impl(typename copied_type::size_type size, sprout::index_tuple, Args&&... args) { - return copied_type{{(Indexes < size ? sprout::forward(args) : T())...}, size}; - } public: template static SPROUT_CONSTEXPR typename copied_type::size_type @@ -724,41 +861,18 @@ namespace sprout { template static SPROUT_CONSTEXPR copied_type make(Args&&... args) { - return make_impl( - length(args...), - sprout::index_pack::make(), - sprout::forward(args)... - ); + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct(length(args...), sprout::forward(args)...); } template static SPROUT_CONSTEXPR copied_type make(typename copied_type::size_type size, Args&&... args) { - return make_impl( - size, - sprout::index_pack::make(), - sprout::forward(args)... - ); + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct(size, sprout::forward(args)...); } }; } // namespace detail - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::basic_string - to_string_impl_1( - T const(& arr)[N], typename sprout::basic_string::size_type n, - sprout::index_tuple - ) - { - return sprout::basic_string{{(Indexes < n ? arr[Indexes] : T())...}, n}; - } - template - inline SPROUT_CONSTEXPR sprout::basic_string - to_string_impl(T const(& arr)[N]) { - typedef sprout::char_traits_helper::traits_type> helper_type; - return to_string_impl_1(arr, helper_type::length(arr, N - 1), sprout::make_index_tuple::make()); - } - } // namespace detail // // to_string // @@ -770,7 +884,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::basic_string to_string(T const(& arr)[N]) { - return sprout::detail::to_string_impl(arr); + return sprout::basic_string(arr); } // diff --git a/sprout/uuid/io.hpp b/sprout/uuid/io.hpp index b5fc90fe..d74232a1 100644 --- a/sprout/uuid/io.hpp +++ b/sprout/uuid/io.hpp @@ -122,47 +122,46 @@ namespace sprout { template > inline SPROUT_CONSTEXPR sprout::basic_string to_string_of(sprout::uuids::uuid const& u) { - return sprout::basic_string{ - { - sprout::uuids::detail::digits::table[(u[0] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[0]) & 0x0F], - sprout::uuids::detail::digits::table[(u[1] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[1]) & 0x0F], - sprout::uuids::detail::digits::table[(u[2] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[2]) & 0x0F], - sprout::uuids::detail::digits::table[(u[3] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[3]) & 0x0F], - sprout::uuids::detail::digits::dash, - sprout::uuids::detail::digits::table[(u[4] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[4]) & 0x0F], - sprout::uuids::detail::digits::table[(u[5] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[5]) & 0x0F], - sprout::uuids::detail::digits::dash, - sprout::uuids::detail::digits::table[(u[6] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[6]) & 0x0F], - sprout::uuids::detail::digits::table[(u[7] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[7]) & 0x0F], - sprout::uuids::detail::digits::dash, - sprout::uuids::detail::digits::table[(u[8] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[8]) & 0x0F], - sprout::uuids::detail::digits::table[(u[9] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[9]) & 0x0F], - sprout::uuids::detail::digits::dash, - sprout::uuids::detail::digits::table[(u[10] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[10]) & 0x0F], - sprout::uuids::detail::digits::table[(u[11] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[11]) & 0x0F], - sprout::uuids::detail::digits::table[(u[12] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[12]) & 0x0F], - sprout::uuids::detail::digits::table[(u[13] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[13]) & 0x0F], - sprout::uuids::detail::digits::table[(u[14] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[14]) & 0x0F], - sprout::uuids::detail::digits::table[(u[15] >> 4) & 0x0F], - sprout::uuids::detail::digits::table[(u[15]) & 0x0F] - }, - 36 - }; + typedef sprout::detail::string_construct_access access_type; + return access_type::raw_construct( + 36, + sprout::uuids::detail::digits::table[(u[0] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[0]) & 0x0F], + sprout::uuids::detail::digits::table[(u[1] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[1]) & 0x0F], + sprout::uuids::detail::digits::table[(u[2] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[2]) & 0x0F], + sprout::uuids::detail::digits::table[(u[3] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[3]) & 0x0F], + sprout::uuids::detail::digits::dash, + sprout::uuids::detail::digits::table[(u[4] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[4]) & 0x0F], + sprout::uuids::detail::digits::table[(u[5] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[5]) & 0x0F], + sprout::uuids::detail::digits::dash, + sprout::uuids::detail::digits::table[(u[6] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[6]) & 0x0F], + sprout::uuids::detail::digits::table[(u[7] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[7]) & 0x0F], + sprout::uuids::detail::digits::dash, + sprout::uuids::detail::digits::table[(u[8] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[8]) & 0x0F], + sprout::uuids::detail::digits::table[(u[9] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[9]) & 0x0F], + sprout::uuids::detail::digits::dash, + sprout::uuids::detail::digits::table[(u[10] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[10]) & 0x0F], + sprout::uuids::detail::digits::table[(u[11] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[11]) & 0x0F], + sprout::uuids::detail::digits::table[(u[12] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[12]) & 0x0F], + sprout::uuids::detail::digits::table[(u[13] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[13]) & 0x0F], + sprout::uuids::detail::digits::table[(u[14] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[14]) & 0x0F], + sprout::uuids::detail::digits::table[(u[15] >> 4) & 0x0F], + sprout::uuids::detail::digits::table[(u[15]) & 0x0F] + ); } // // to_string