[Destructive changes] add sprout::string constructor (already not an aggregate)

This commit is contained in:
bolero-MURAKAMI 2013-08-09 19:04:37 +09:00
parent cb1077d247
commit baf8995e81
17 changed files with 466 additions and 301 deletions

View file

@ -25,6 +25,60 @@ namespace testspr {
TESTSPR_BOTH_ASSERT((std::is_same<decltype(str1), sprout::basic_string<char, 10> const>::value)); TESTSPR_BOTH_ASSERT((std::is_same<decltype(str1), sprout::basic_string<char, 10> const>::value));
TESTSPR_BOTH_ASSERT((std::is_same<decltype(str2), sprout::basic_string<char, 8> const>::value)); TESTSPR_BOTH_ASSERT((std::is_same<decltype(str2), sprout::basic_string<char, 8> 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<decltype(str1)>::type s1 = str2;
TESTSPR_BOTH_ASSERT(s1 == str2);
}
{
SPROUT_STATIC_CONSTEXPR auto s1 = std::decay<decltype(str1)>::type(str1, 6);
TESTSPR_BOTH_ASSERT(s1 == "1234");
}
{
SPROUT_STATIC_CONSTEXPR auto s1 = std::decay<decltype(str1)>::type(str1, 0, 6);
TESTSPR_BOTH_ASSERT(s1 == "foobar");
}
{
SPROUT_STATIC_CONSTEXPR auto s1 = std::decay<decltype(str1)>::type(str2, 4);
TESTSPR_BOTH_ASSERT(s1 == "hoge");
}
{
SPROUT_STATIC_CONSTEXPR auto s1 = std::decay<decltype(str1)>::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<char const*>(cstr));
TESTSPR_BOTH_ASSERT(s1 == cstr);
}
{
SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(static_cast<char const*>(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 // begin
TESTSPR_BOTH_ASSERT(cstr[0] == *str1.begin()); TESTSPR_BOTH_ASSERT(cstr[0] == *str1.begin());

View file

@ -26,10 +26,10 @@ namespace sprout {
template<typename ForwardIterator, typename T, typename Compare> template<typename ForwardIterator, typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator, ForwardIterator> inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, T const& value, Compare comp) { equal_range(ForwardIterator first, ForwardIterator last, T const& value, Compare comp) {
return sprout::pair<ForwardIterator, ForwardIterator>{ return sprout::pair<ForwardIterator, ForwardIterator>(
sprout::lower_bound(first, last, value, comp), sprout::lower_bound(first, last, value, comp),
sprout::upper_bound(first, last, value, comp) sprout::upper_bound(first, last, value, comp)
}; );
} }
template<typename ForwardIterator, typename T> template<typename ForwardIterator, typename T>

View file

@ -24,9 +24,9 @@ namespace sprout {
template<typename RandomAccessIterator1, typename RandomAccessIterator2> template<typename RandomAccessIterator1, typename RandomAccessIterator2>
inline SPROUT_CONSTEXPR sprout::pair<RandomAccessIterator1, RandomAccessIterator2> inline SPROUT_CONSTEXPR sprout::pair<RandomAccessIterator1, RandomAccessIterator2>
mismatch_impl_check(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) { mismatch_impl_check(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) {
return sprout::pair<RandomAccessIterator1, RandomAccessIterator2>{ return sprout::pair<RandomAccessIterator1, RandomAccessIterator2>(
found, sprout::next(first2, sprout::distance(first1, found)) found, sprout::next(first2, sprout::distance(first1, found))
}; );
} }
template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate> template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
@ -59,7 +59,7 @@ namespace sprout {
std::random_access_iterator_tag* std::random_access_iterator_tag*
) )
{ {
return first1 == last1 ? sprout::pair<RandomAccessIterator1, RandomAccessIterator2>{first1, first2} return first1 == last1 ? sprout::pair<RandomAccessIterator1, RandomAccessIterator2>(first1, first2)
: sprout::detail::mismatch_impl_check( : sprout::detail::mismatch_impl_check(
first1, first2, first1, first2,
sprout::detail::mismatch_impl_ra( sprout::detail::mismatch_impl_ra(
@ -190,7 +190,7 @@ namespace sprout {
std::random_access_iterator_tag* std::random_access_iterator_tag*
) )
{ {
return first1 == last1 || first2 == last2 ? sprout::pair<RandomAccessIterator1, RandomAccessIterator2>{first1, first2} return first1 == last1 || first2 == last2 ? sprout::pair<RandomAccessIterator1, RandomAccessIterator2>(first1, first2)
: sprout::detail::mismatch_impl_check( : sprout::detail::mismatch_impl_check(
first1, first2, first1, first2,
sprout::detail::mismatch2_impl_ra( sprout::detail::mismatch2_impl_ra(

View file

@ -10,6 +10,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cmath>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/limits.hpp> #include <sprout/limits.hpp>

View file

@ -34,7 +34,7 @@ namespace sprout {
// //
// float_exponent10 // float_exponent10
// //
// !!! // !!! TODO: O(logN)
template<typename FloatType> template<typename FloatType>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
float_exponent10_positive(FloatType val) { float_exponent10_positive(FloatType val) {

View file

@ -710,9 +710,9 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR auto inline SPROUT_CONSTEXPR auto
eval(sprout::io::format_holder<T> const& holder) eval(sprout::io::format_holder<T> const& holder)
-> decltype(sprout::basic_string<Elem, 1>{{static_cast<Elem>(holder.value())}, 1}) -> decltype(sprout::detail::string_construct_access<Elem, 1>::raw_construct(1, static_cast<Elem>(holder.value())))
{ {
return sprout::basic_string<Elem, 1>{{static_cast<Elem>(holder.value())}, 1}; return sprout::detail::string_construct_access<Elem, 1>::raw_construct(1, static_cast<Elem>(holder.value()));
} }
template< template<
typename Elem, std::size_t N, typename T, typename Elem, std::size_t N, typename T,
@ -753,17 +753,16 @@ namespace sprout {
template<typename Elem, std::size_t N, sprout::index_t... Indexes, std::size_t K, typename... Args> template<typename Elem, std::size_t N, sprout::index_t... Indexes, std::size_t K, typename... Args>
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, N> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, N>
output_impl_1(sprout::index_tuple<Indexes...>, sprout::array<std::size_t, K> const& sizes, Args const&... args) { output_impl_1(sprout::index_tuple<Indexes...>, sprout::array<std::size_t, K> const& sizes, Args const&... args) {
return sprout::basic_string<Elem, N>{ typedef sprout::detail::string_construct_access<Elem, N> access_type;
{ return access_type::raw_construct(
sprout::io::detail::get_param<Elem>( NS_SSCRISK_CEL_OR_SPROUT::min(sizes.back(), N),
sprout::range::lower_bound(sizes, static_cast<std::size_t>(Indexes + 1)), sprout::io::detail::get_param<Elem>(
sizes, sprout::range::lower_bound(sizes, static_cast<std::size_t>(Indexes + 1)),
Indexes, sizes,
args... Indexes,
)... args...
}, )...
NS_SSCRISK_CEL_OR_SPROUT::min(sizes.back(), N) );
};
} }
template<typename Elem, std::size_t N, typename... Args> template<typename Elem, std::size_t N, typename... Args>
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, N> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, N>

View file

@ -10,18 +10,32 @@
#include <cstddef> #include <cstddef>
#include <functional> #include <functional>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/logic/tribool/tribool.hpp> #include <sprout/logic/tribool/tribool.hpp>
#include <sprout/functional/hash.hpp> #include <sprout/functional/hash.hpp>
namespace sprout { namespace sprout {
// //
// hash_value // hash_value_traits
// //
inline SPROUT_CONSTEXPR std::size_t template<>
hash_value(sprout::logic::indeterminate_keyword_t) { struct hash_value_traits<sprout::logic::indeterminate_keyword_t> {
return sprout::logic::tribool::indeterminate_value; 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<std::remove_pointer<sprout::logic::indeterminate_keyword_t>::type> {
public:
static SPROUT_CONSTEXPR std::size_t
hash_value(sprout::logic::indeterminate_keyword_t) {
return sprout::logic::tribool::indeterminate_value;
}
};
namespace logic { namespace logic {
// //
// hash_value // hash_value

View file

@ -118,10 +118,11 @@ namespace sprout {
: init(true) : init(true)
, val(v) , val(v)
{} {}
SPROUT_CONSTEXPR optional(T&& v) // !!! for T const&
: init(true) // SPROUT_CONSTEXPR optional(T&& v)
, val(sprout::move(v)) // : init(true)
{} // , val(sprout::move(v))
// {}
template< template<
typename... Args, typename... Args,
typename = typename std::enable_if<is_constructible_args<Args...>::value>::type typename = typename std::enable_if<is_constructible_args<Args...>::value>::type
@ -142,10 +143,11 @@ namespace sprout {
: init(cond) : init(cond)
, val(cond ? holder_type(v) : holder_type()) , val(cond ? holder_type(v) : holder_type())
{} {}
SPROUT_CONSTEXPR optional(bool cond, T&& v) // !!! for T const&
: init(cond) // SPROUT_CONSTEXPR optional(bool cond, T&& v)
, val(cond ? holder_type(sprout::move(v)) : holder_type()) // : init(cond)
{} // , val(cond ? holder_type(sprout::move(v)) : holder_type())
// {}
template<typename U> template<typename U>
explicit SPROUT_CONSTEXPR optional(optional<U> const& v) explicit SPROUT_CONSTEXPR optional(optional<U> const& v)
: init(v.is_initialized()) : init(v.is_initialized())

View file

@ -24,7 +24,8 @@ namespace sprout {
struct rational_private_constructor_tag {}; struct rational_private_constructor_tag {};
template<typename IntType> template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType> make_rational( inline SPROUT_CONSTEXPR sprout::rational<IntType>
make_rational(
typename sprout::detail::call_traits<IntType>::param_type n, typename sprout::detail::call_traits<IntType>::param_type n,
typename sprout::detail::call_traits<IntType>::param_type d, typename sprout::detail::call_traits<IntType>::param_type d,
sprout::detail::rational_private_constructor_tag sprout::detail::rational_private_constructor_tag

View file

@ -25,15 +25,14 @@ namespace sprout {
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, N + 1, Traits>{ typedef sprout::detail::string_construct_access<T, N + 1, Traits> access_type;
{ return access_type::raw_construct(
(Indexes < lsize ? lhs[Indexes] lsize + 1,
: Indexes < lsize + 1 ? rhs (Indexes < lsize ? lhs[Indexes]
: T() : Indexes < lsize + 1 ? rhs
)... : T()
}, )...
lsize + 1 );
};
} }
template<typename T, std::size_t N, typename Traits, sprout::index_t... Indexes> template<typename T, std::size_t N, typename Traits, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, 1 + N, Traits> inline SPROUT_CONSTEXPR sprout::basic_string<T, 1 + N, Traits>
@ -43,15 +42,14 @@ namespace sprout {
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, 1 + N, Traits>{ typedef sprout::detail::string_construct_access<T, 1 + N, Traits> access_type;
{ return access_type::raw_construct(
(Indexes < 1 ? lhs 1 + rsize,
: Indexes < 1 + rsize ? rhs[Indexes - 1] (Indexes < 1 ? lhs
: T() : Indexes < 1 + rsize ? rhs[Indexes - 1]
)... : T()
}, )...
1 + rsize );
};
} }
template<typename T, std::size_t N, typename Traits, std::size_t M, sprout::index_t... Indexes> template<typename T, std::size_t N, typename Traits, std::size_t M, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N + (M - 1), Traits> inline SPROUT_CONSTEXPR sprout::basic_string<T, N + (M - 1), Traits>
@ -61,15 +59,14 @@ namespace sprout {
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, N + (M - 1), Traits>{ typedef sprout::detail::string_construct_access<T, N + (M - 1), Traits> access_type;
{ return access_type::raw_construct(
(Indexes < lsize ? lhs[Indexes] lsize + rsize,
: Indexes < lsize + rsize ? rhs[Indexes - lsize] (Indexes < lsize ? lhs[Indexes]
: T() : Indexes < lsize + rsize ? rhs[Indexes - lsize]
)... : T()
}, )...
lsize + rsize );
};
} }
template<typename T, std::size_t N, typename Traits, std::size_t M, sprout::index_t... Indexes> template<typename T, std::size_t N, typename Traits, std::size_t M, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, (M - 1) + N, Traits> inline SPROUT_CONSTEXPR sprout::basic_string<T, (M - 1) + N, Traits>
@ -79,15 +76,14 @@ namespace sprout {
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, (M - 1) + N, Traits>{ typedef sprout::detail::string_construct_access<T, (M - 1) + N, Traits> access_type;
{ return access_type::raw_construct(
(Indexes < lsize ? lhs[Indexes] lsize + rsize,
: Indexes < lsize + rsize ? rhs[Indexes - lsize] (Indexes < lsize ? lhs[Indexes]
: T() : Indexes < lsize + rsize ? rhs[Indexes - lsize]
)... : T()
}, )...
lsize + rsize );
};
} }
template<typename T, std::size_t N1, std::size_t N2, typename Traits, sprout::index_t... Indexes> template<typename T, std::size_t N1, std::size_t N2, typename Traits, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N1 + N2, Traits> inline SPROUT_CONSTEXPR sprout::basic_string<T, N1 + N2, Traits>
@ -97,15 +93,14 @@ namespace sprout {
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, N1 + N2, Traits>{ typedef sprout::detail::string_construct_access<T, N1 + N2, Traits> access_type;
{ return access_type::raw_construct(
(Indexes < lsize ? lhs[Indexes] lsize + rsize,
: Indexes < lsize + rsize ? rhs[Indexes - lsize] (Indexes < lsize ? lhs[Indexes]
: T() : Indexes < lsize + rsize ? rhs[Indexes - lsize]
)... : T()
}, )...
lsize + rsize );
};
} }
} // namespace detail } // namespace detail

View file

@ -44,31 +44,27 @@ namespace sprout {
template<typename Elem, typename FloatType, sprout::index_t... Indexes> template<typename Elem, typename FloatType, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value>
float_to_string_impl(FloatType val, bool negative, int digits, int v, sprout::index_tuple<Indexes...>) { float_to_string_impl(FloatType val, bool negative, int digits, int v, sprout::index_tuple<Indexes...>) {
typedef sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value> type; typedef sprout::detail::string_construct_access<Elem, sprout::printed_float_digits<FloatType>::value> access_type;
return negative return negative
? type{ ? access_type::raw_construct(
{ static_cast<std::size_t>(digits + 2 + sprout::detail::decimal_places_length),
static_cast<Elem>('-'), static_cast<Elem>('-'),
(Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) (Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, digits - 1 - Indexes))
: Indexes == digits ? static_cast<Elem>('.') : Indexes == digits ? static_cast<Elem>('.')
: Indexes < digits + 1 + sprout::detail::decimal_places_length : Indexes < digits + 1 + sprout::detail::decimal_places_length
? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes))
: Elem() : Elem()
)... )...
}, )
static_cast<std::size_t>(digits + 2 + sprout::detail::decimal_places_length) : access_type::raw_construct(
} static_cast<std::size_t>(digits + 1 + sprout::detail::decimal_places_length),
: type{ (Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, digits - 1 - Indexes))
{ : Indexes == digits ? static_cast<Elem>('.')
(Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) : Indexes < digits + 1 + sprout::detail::decimal_places_length
: Indexes == digits ? static_cast<Elem>('.') ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes))
: Indexes < digits + 1 + sprout::detail::decimal_places_length : Elem()
? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) )...
: Elem() )
)...
},
static_cast<std::size_t>(digits + 1 + sprout::detail::decimal_places_length)
}
; ;
} }
template<typename Elem, typename FloatType> template<typename Elem, typename FloatType>
@ -90,13 +86,13 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value>
float_to_string(FloatType val) { float_to_string(FloatType val) {
typedef sprout::basic_string<Elem, sprout::printed_float_digits<FloatType>::value> type; typedef sprout::detail::string_construct_access<Elem, sprout::printed_float_digits<FloatType>::value> access_type;
return sprout::math::isinf(val) ? sprout::math::signbit(val) return sprout::math::isinf(val) ? sprout::math::signbit(val)
? type{{static_cast<Elem>('-'), static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f')}, 4} ? access_type::raw_construct(4, static_cast<Elem>('-'), static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f'))
: type{{static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f')}, 3} : access_type::raw_construct(3, static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f'))
: sprout::math::isnan(val) ? sprout::math::signbit(val) : sprout::math::isnan(val) ? sprout::math::signbit(val)
? type{{static_cast<Elem>('-'), static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n')}, 4} ? access_type::raw_construct(4, static_cast<Elem>('-'), static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n'))
: type{{static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n')}, 3} : access_type::raw_construct(3, static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n'))
: sprout::detail::float_to_string<Elem>( : sprout::detail::float_to_string<Elem>(
sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length), sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length),
sprout::math::signbit(val), sprout::math::signbit(val),
@ -130,39 +126,35 @@ namespace sprout {
template<typename Elem, typename FloatType, sprout::index_t... Indexes> template<typename Elem, typename FloatType, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value>
float_to_string_exp(FloatType val, bool negative, int exponent10, int e10_digits, sprout::index_tuple<Indexes...>) { float_to_string_exp(FloatType val, bool negative, int exponent10, int e10_digits, sprout::index_tuple<Indexes...>) {
typedef sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value> type; typedef sprout::detail::string_construct_access<Elem, sprout::printed_float_exp_digits<FloatType>::value> access_type;
return negative return negative
? type{ ? access_type::raw_construct(
{ static_cast<std::size_t>(5 + sprout::detail::decimal_places_length + e10_digits),
static_cast<Elem>('-'), static_cast<Elem>('-'),
(Indexes == 0 ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 0)) (Indexes == 0 ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 0))
: Indexes == 1 ? static_cast<Elem>('.') : Indexes == 1 ? static_cast<Elem>('.')
: Indexes < 2 + sprout::detail::decimal_places_length : Indexes < 2 + sprout::detail::decimal_places_length
? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 1 - Indexes)) ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 1 - Indexes))
: Indexes == 2 + sprout::detail::decimal_places_length ? static_cast<Elem>('e') : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast<Elem>('e')
: Indexes == 3 + sprout::detail::decimal_places_length ? static_cast<Elem>(exponent10 < 0 ? '-' : '+') : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast<Elem>(exponent10 < 0 ? '-' : '+')
: Indexes < 4 + sprout::detail::decimal_places_length + e10_digits : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits
? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes))
: Elem() : Elem()
)... )...
}, )
static_cast<std::size_t>(5 + sprout::detail::decimal_places_length + e10_digits) : access_type::raw_construct(
} static_cast<std::size_t>(4 + sprout::detail::decimal_places_length + e10_digits),
: type{ (Indexes == 0 ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 0))
{ : Indexes == 1 ? static_cast<Elem>('.')
(Indexes == 0 ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 0)) : Indexes < 2 + sprout::detail::decimal_places_length
: Indexes == 1 ? static_cast<Elem>('.') ? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 1 - Indexes))
: Indexes < 2 + sprout::detail::decimal_places_length : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast<Elem>('e')
? sprout::detail::int_to_char<Elem>(sprout::detail::float_digit_at(val, 1 - Indexes)) : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast<Elem>(exponent10 < 0 ? '-' : '+')
: Indexes == 2 + sprout::detail::decimal_places_length ? static_cast<Elem>('e') : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits
: Indexes == 3 + sprout::detail::decimal_places_length ? static_cast<Elem>(exponent10 < 0 ? '-' : '+') ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes))
: Indexes < 4 + sprout::detail::decimal_places_length + e10_digits : Elem()
? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) )...
: Elem() )
)...
},
static_cast<std::size_t>(4 + sprout::detail::decimal_places_length + e10_digits)
}
; ;
} }
} // namespace detail } // namespace detail
@ -176,13 +168,13 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value>
float_to_string_exp(FloatType val) { float_to_string_exp(FloatType val) {
typedef sprout::basic_string<Elem, sprout::printed_float_exp_digits<FloatType>::value> type; typedef sprout::detail::string_construct_access<Elem, sprout::printed_float_exp_digits<FloatType>::value> access_type;
return sprout::math::isinf(val) ? sprout::math::signbit(val) return sprout::math::isinf(val) ? sprout::math::signbit(val)
? type{{static_cast<Elem>('-'), static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f')}, 4} ? access_type::raw_construct(4, static_cast<Elem>('-'), static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f'))
: type{{static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f')}, 3} : access_type::raw_construct(3, static_cast<Elem>('i'), static_cast<Elem>('n'), static_cast<Elem>('f'))
: sprout::math::isnan(val) ? sprout::math::signbit(val) : sprout::math::isnan(val) ? sprout::math::signbit(val)
? type{{static_cast<Elem>('-'), static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n')}, 4} ? access_type::raw_construct(4, static_cast<Elem>('-'), static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n'))
: type{{static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n')}, 3} : access_type::raw_construct(3, static_cast<Elem>('n'), static_cast<Elem>('a'), static_cast<Elem>('n'))
: sprout::detail::float_to_string_exp<Elem>( : sprout::detail::float_to_string_exp<Elem>(
sprout::detail::float_round_at( sprout::detail::float_round_at(
(val < 0 ? -val : val) / sprout::detail::float_pow10<FloatType>(sprout::detail::float_exponent10(val)), (val < 0 ? -val : val) / sprout::detail::float_pow10<FloatType>(sprout::detail::float_exponent10(val)),

View file

@ -38,23 +38,20 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value>
int_to_string(IntType val, int digits, sprout::index_tuple<Indexes...>) { int_to_string(IntType val, int digits, sprout::index_tuple<Indexes...>) {
return val < 0 ? sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value>{ typedef sprout::detail::string_construct_access<Elem, sprout::printed_integer_digits<IntType, Base>::value> access_type;
{ return val < 0 ? access_type::raw_construct(
static_cast<Elem>('-'), static_cast<std::size_t>(digits + 1),
(Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes)) static_cast<Elem>('-'),
: Elem() (Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes))
)... : Elem()
}, )...
static_cast<std::size_t>(digits + 1) )
} : access_type::raw_construct(
: sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value>{ static_cast<std::size_t>(digits),
{ (Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes))
(Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes)) : Elem()
: Elem() )...
)... )
},
static_cast<std::size_t>(digits)
}
; ;
} }
template< template<
@ -64,14 +61,13 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value>
int_to_string(IntType val, int digits, sprout::index_tuple<Indexes...>) { int_to_string(IntType val, int digits, sprout::index_tuple<Indexes...>) {
return sprout::basic_string<Elem, sprout::printed_integer_digits<IntType, Base>::value>{ typedef sprout::detail::string_construct_access<Elem, sprout::printed_integer_digits<IntType, Base>::value> access_type;
{ return access_type::raw_construct(
(Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes)) static_cast<std::size_t>(digits),
: Elem() (Indexes < digits ? sprout::detail::int_to_char<Elem>(sprout::detail::int_digit_at<Base>(val, digits - 1 - Indexes))
)... : Elem()
}, )...
static_cast<std::size_t>(digits) );
};
} }
} // namespace detail } // namespace detail

View file

@ -58,10 +58,7 @@ namespace sprout {
state |= std::ios_base::failbit; state |= std::ios_base::failbit;
} }
lhs.setstate(state); lhs.setstate(state);
rhs.len = current; rhs.resize(current);
for (; current != rhs.max_size(); ++current) {
rhs[current] = T();
}
return lhs; return lhs;
} }
template<typename T, std::size_t N, typename Traits, typename StreamTraits> template<typename T, std::size_t N, typename Traits, typename StreamTraits>

View file

@ -34,7 +34,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::basic_string<typename std::decay<T>::type, 0> inline SPROUT_CONSTEXPR sprout::basic_string<typename std::decay<T>::type, 0>
make_string_as() { make_string_as() {
return sprout::basic_string<typename std::decay<T>::type, 0>{}; return sprout::basic_string<typename std::decay<T>::type, 0>();
} }
template<typename T, typename... Types> template<typename T, typename... Types>
inline SPROUT_CONSTEXPR sprout::basic_string<typename std::decay<T>::type, sizeof...(Types)> inline SPROUT_CONSTEXPR sprout::basic_string<typename std::decay<T>::type, sizeof...(Types)>

View file

@ -27,14 +27,15 @@ namespace sprout {
private: private:
typedef sprout::value_holder<string_type const&> holder_type; typedef sprout::value_holder<string_type const&> holder_type;
private: private:
template<std::size_t M, sprout::index_t... Indexes> template<sprout::index_t... Indexes>
static SPROUT_CONSTEXPR sprout::basic_string<T, sizeof...(Indexes), Traits> static SPROUT_CONSTEXPR sprout::basic_string<T, sizeof...(Indexes), Traits>
implicit_conversion_impl( implicit_conversion_impl(
T const(& elems)[M], std::size_t len, string_type const& str, std::size_t len,
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::basic_string<T, sizeof...(Indexes), Traits>{{(Indexes < M - 1 ? elems[Indexes] : T())...}, len}; typedef sprout::detail::string_construct_access<T, sizeof...(Indexes), Traits> access_type;
return access_type::raw_construct(len, (Indexes < N ? str[Indexes] : T())...);
} }
private: private:
holder_type holder_; holder_type holder_;
@ -50,8 +51,8 @@ namespace sprout {
template<std::size_t N2> template<std::size_t N2>
SPROUT_CONSTEXPR operator sprout::basic_string<T, N2, Traits>() const { SPROUT_CONSTEXPR operator sprout::basic_string<T, N2, Traits>() const {
return implicit_conversion_impl( return implicit_conversion_impl(
holder_.get().elems, holder_.get(),
NS_SSCRISK_CEL_OR_SPROUT::min(N2, holder_.get().len), NS_SSCRISK_CEL_OR_SPROUT::min(N2, holder_.get().size()),
sprout::make_index_tuple<(N < N2 ? N : N2)>::make() sprout::make_index_tuple<(N < N2 ? N : N2)>::make()
); );
} }

View file

@ -14,6 +14,7 @@
#include <utility> #include <utility>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
#include <initializer_list>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/metafunction.hpp> #include <sprout/index_tuple/metafunction.hpp>
#include <sprout/array/array.hpp> #include <sprout/array/array.hpp>
@ -23,6 +24,7 @@
#include <sprout/algorithm/find.hpp> #include <sprout/algorithm/find.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
#include <sprout/utility/swap.hpp> #include <sprout/utility/swap.hpp>
#include <sprout/math/comparison.hpp>
#include <sprout/string/char_traits.hpp> #include <sprout/string/char_traits.hpp>
#include <sprout/string/npos.hpp> #include <sprout/string/npos.hpp>
#include <sprout/string/detail/operations.hpp> #include <sprout/string/detail/operations.hpp>
@ -32,31 +34,105 @@
#endif #endif
namespace sprout { namespace sprout {
namespace detail {
struct string_raw_construct_t {};
struct string_from_c_str_construct_t {};
template<typename T, std::size_t N, typename Traits = sprout::char_traits<T> >
class string_construct_access;
template<typename T, std::size_t N, typename Traits>
class basic_string_impl {
friend class sprout::detail::string_construct_access<T, N, Traits>;
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<typename String, sprout::index_t... Indexes>
SPROUT_CONSTEXPR basic_string_impl(
sprout::index_tuple<Indexes...>,
String const& str, size_type pos, size_type n
)
: elems{
(sprout::math::less(Indexes, n) ? str[Indexes + pos]
: value_type()
)...
}
, len(n)
{}
template<typename String, sprout::index_t... Indexes>
SPROUT_CONSTEXPR basic_string_impl(
sprout::index_tuple<Indexes...>,
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<typename... Args, sprout::index_t... Indexes>
SPROUT_CONSTEXPR basic_string_impl(
sprout::index_tuple<Indexes...>,
sprout::detail::string_raw_construct_t, size_type n, Args&&... args
)
: elems{
(sprout::math::less(Indexes, n) ? sprout::forward<Args>(args)
: value_type()
)...
}
, len(n)
{}
};
} // namespace detail
// //
// basic_string // basic_string
// //
template<typename T, std::size_t N, typename Traits = sprout::char_traits<T> > template<typename T, std::size_t N, typename Traits = sprout::char_traits<T> >
class basic_string { class basic_string
public: : private sprout::detail::basic_string_impl<T, N, Traits>
typedef T value_type; {
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION friend class sprout::detail::string_construct_access<T, N, Traits>;
typedef sprout::index_iterator<basic_string&, true> iterator;
typedef sprout::index_iterator<basic_string const&, true> 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<iterator> reverse_iterator;
typedef sprout::reverse_iterator<const_iterator> const_reverse_iterator;
typedef Traits traits_type;
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
private: private:
typedef sprout::detail::basic_string_impl<T, N, Traits> 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<basic_string&, true> iterator;
typedef sprout::index_iterator<basic_string const&, true> const_iterator;
#else
typedef T* iterator;
typedef T const* const_iterator;
#endif
typedef sprout::reverse_iterator<iterator> reverse_iterator;
typedef sprout::reverse_iterator<const_iterator> const_reverse_iterator;
private:
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
template<typename Iterator> template<typename Iterator>
class is_string_iterator class is_string_iterator
: public std::false_type : public std::false_type
@ -85,36 +161,99 @@ namespace sprout {
public: public:
SPROUT_STATIC_CONSTEXPR size_type npos = sprout::npos_t::get<size_type>::value; SPROUT_STATIC_CONSTEXPR size_type npos = sprout::npos_t::get<size_type>::value;
SPROUT_STATIC_CONSTEXPR size_type static_size = N; SPROUT_STATIC_CONSTEXPR size_type static_size = N;
private:
template<sprout::index_t... Indexes>
static SPROUT_CONSTEXPR basic_string
from_c_str_impl(value_type const* s, size_type n, sprout::index_tuple<Indexes...>) {
return basic_string{{(Indexes < n ? s[Indexes] : T())...}, n};
}
template<std::size_t M, sprout::index_t... Indexes>
static SPROUT_CONSTEXPR basic_string<T, sizeof...(Indexes), Traits>
implicit_conversion_impl(T const(& elems)[M], size_type len, sprout::index_tuple<Indexes...>) {
return sprout::basic_string<T, sizeof...(Indexes), Traits>{{(Indexes < M - 1 ? elems[Indexes] : T())...}, len};
}
public: public:
static SPROUT_CONSTEXPR basic_string from_c_str(T const* s, size_type n) { static SPROUT_CONSTEXPR basic_string from_c_str(T const* s, size_type n) {
return !(N < n) return basic_string(s, n);
? from_c_str_impl(s, n, sprout::make_index_tuple<N>::make())
: throw std::out_of_range("basic_string<>: index out of range")
;
} }
static SPROUT_CONSTEXPR basic_string from_c_str(T const* s) { 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<T, Traits> const& s) { static SPROUT_CONSTEXPR basic_string from_c_str(std::basic_string<T, Traits> const& s) {
return from_c_str(s.data(), s.size()); return from_c_str(s.data(), s.size());
} }
public: private:
value_type elems[static_size + 1]; using impl_type::elems;
size_type len; using impl_type::len;
private:
template<typename... Args, typename Enable = typename std::enable_if<(sizeof...(Args) <= N)>::type>
SPROUT_CONSTEXPR basic_string(sprout::detail::string_raw_construct_t, size_type n, Args&&... args)
: impl_type(
sprout::index_pack<Args...>::make(),
sprout::detail::string_raw_construct_t(), n, sprout::forward<Args>(args)...
)
{}
public: public:
// construct/copy/destroy: // construct/copy/destroy:
template<std::size_t N2> SPROUT_CONSTEXPR basic_string() = default;
SPROUT_CONSTEXPR basic_string(basic_string const&) = default;
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 < N)>::type>
SPROUT_CONSTEXPR basic_string(basic_string<T, N2, Traits> const& str)
: impl_type(
sprout::make_index_tuple<N2>::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<N>::make(),
str, pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos)
)
{}
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 < N)>::type>
SPROUT_CONSTEXPR basic_string(basic_string<T, N2, Traits> const& str, size_type pos, size_type n = npos)
: impl_type(
sprout::make_index_tuple<N2>::make(),
str, pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos)
)
{}
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 - 1 <= N)>::type>
SPROUT_CONSTEXPR basic_string(T const(& arr)[N2])
: impl_type(
sprout::make_index_tuple<N2 - 1>::make(),
arr, 0, sprout::char_traits_helper<typename sprout::basic_string<T, N2 - 1>::traits_type>::length(arr, N2 - 1)
)
{}
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 - 1 <= N)>::type>
SPROUT_CONSTEXPR basic_string(T const(& arr)[N2], size_type n)
: impl_type(
sprout::make_index_tuple<N2 - 1>::make(),
arr, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, sprout::char_traits_helper<typename sprout::basic_string<T, N2 - 1>::traits_type>::length(arr, N2 - 1))
)
{}
SPROUT_CONSTEXPR basic_string(value_type const* s)
: impl_type(
sprout::make_index_tuple<N>::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<N>::make(),
sprout::detail::string_from_c_str_construct_t(), s, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, traits_type::length(s))
)
{}
// !!!
// template<typename InputIterator>
// SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last);
template<typename RandomAccessIterator>
SPROUT_CONSTEXPR basic_string(RandomAccessIterator first, RandomAccessIterator last)
: impl_type(
sprout::make_index_tuple<N>::make(),
sprout::detail::string_from_c_str_construct_t(), first, 0, sprout::distance(first, last)
)
{}
basic_string(std::initializer_list<value_type> il)
: impl_type(
sprout::make_index_tuple<N>::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<std::size_t N2, typename Enable = typename std::enable_if<(N2 != N)>::type>
basic_string& basic_string&
operator=(basic_string<T, N2, Traits> const& rhs) { operator=(basic_string<T, N2, Traits> const& rhs) {
return assign(rhs); return assign(rhs);
@ -493,13 +632,6 @@ namespace sprout {
; ;
} }
// others: // others:
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 > N)>::type>
SPROUT_CONSTEXPR operator basic_string<T, N2, Traits>() const {
return implicit_conversion_impl(
elems, size(),
sprout::make_index_tuple<N2>::make()
);
}
template<typename Allocator> template<typename Allocator>
SPROUT_EXPLICIT_CONVERSION operator std::basic_string<T, Traits, Allocator>() const { SPROUT_EXPLICIT_CONVERSION operator std::basic_string<T, Traits, Allocator>() const {
return std::basic_string<T, Traits, Allocator>(data(), size()); return std::basic_string<T, Traits, Allocator>(data(), size());
@ -697,6 +829,16 @@ namespace sprout {
} }
namespace detail { namespace detail {
template<typename T, std::size_t N, typename Traits>
class string_construct_access {
public:
template<typename... Args>
static SPROUT_CONSTEXPR sprout::basic_string<T, N, Traits>
raw_construct(typename sprout::basic_string<T, N, Traits>::size_type n, Args&&... args) {
return sprout::basic_string<T, N, Traits>(sprout::detail::string_raw_construct_t(), n, sprout::forward<Args>(args)...);
}
};
template<typename Container> template<typename Container>
struct make_construct_impl; struct make_construct_impl;
@ -710,11 +852,6 @@ namespace sprout {
length_impl(sprout::array<T, M> const& arr) { length_impl(sprout::array<T, M> const& arr) {
return sprout::distance(arr.begin(), sprout::find(arr.begin(), arr.end(), T())); return sprout::distance(arr.begin(), sprout::find(arr.begin(), arr.end(), T()));
} }
template<typename... Args, sprout::index_t... Indexes>
static SPROUT_CONSTEXPR copied_type
make_impl(typename copied_type::size_type size, sprout::index_tuple<Indexes...>, Args&&... args) {
return copied_type{{(Indexes < size ? sprout::forward<Args>(args) : T())...}, size};
}
public: public:
template<typename... Args> template<typename... Args>
static SPROUT_CONSTEXPR typename copied_type::size_type static SPROUT_CONSTEXPR typename copied_type::size_type
@ -724,41 +861,18 @@ namespace sprout {
template<typename... Args> template<typename... Args>
static SPROUT_CONSTEXPR copied_type static SPROUT_CONSTEXPR copied_type
make(Args&&... args) { make(Args&&... args) {
return make_impl( typedef sprout::detail::string_construct_access<T, N, Traits> access_type;
length(args...), return access_type::raw_construct(length(args...), sprout::forward<Args>(args)...);
sprout::index_pack<Args...>::make(),
sprout::forward<Args>(args)...
);
} }
template<typename... Args> template<typename... Args>
static SPROUT_CONSTEXPR copied_type static SPROUT_CONSTEXPR copied_type
make(typename copied_type::size_type size, Args&&... args) { make(typename copied_type::size_type size, Args&&... args) {
return make_impl( typedef sprout::detail::string_construct_access<T, N, Traits> access_type;
size, return access_type::raw_construct(size, sprout::forward<Args>(args)...);
sprout::index_pack<Args...>::make(),
sprout::forward<Args>(args)...
);
} }
}; };
} // namespace detail } // namespace detail
namespace detail {
template<typename T, std::size_t N, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N - 1>
to_string_impl_1(
T const(& arr)[N], typename sprout::basic_string<T, N - 1>::size_type n,
sprout::index_tuple<Indexes...>
)
{
return sprout::basic_string<T, N - 1>{{(Indexes < n ? arr[Indexes] : T())...}, n};
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N - 1>
to_string_impl(T const(& arr)[N]) {
typedef sprout::char_traits_helper<typename sprout::basic_string<T, N - 1>::traits_type> helper_type;
return to_string_impl_1(arr, helper_type::length(arr, N - 1), sprout::make_index_tuple<N - 1>::make());
}
} // namespace detail
// //
// to_string // to_string
// //
@ -770,7 +884,7 @@ namespace sprout {
template<typename T, std::size_t N> template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N - 1> inline SPROUT_CONSTEXPR sprout::basic_string<T, N - 1>
to_string(T const(& arr)[N]) { to_string(T const(& arr)[N]) {
return sprout::detail::to_string_impl(arr); return sprout::basic_string<T, N - 1>(arr);
} }
// //

View file

@ -122,47 +122,46 @@ namespace sprout {
template<typename Elem, typename Traits = sprout::char_traits<Elem> > template<typename Elem, typename Traits = sprout::char_traits<Elem> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, 36, Traits> inline SPROUT_CONSTEXPR sprout::basic_string<Elem, 36, Traits>
to_string_of(sprout::uuids::uuid const& u) { to_string_of(sprout::uuids::uuid const& u) {
return sprout::basic_string<Elem, 36, Traits>{ typedef sprout::detail::string_construct_access<Elem, 36, Traits> access_type;
{ return access_type::raw_construct(
sprout::uuids::detail::digits<Elem>::table[(u[0] >> 4) & 0x0F], 36,
sprout::uuids::detail::digits<Elem>::table[(u[0]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[0] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[1] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[0]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[1]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[1] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[2] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[1]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[2]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[2] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[3] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[2]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[3]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[3] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash, sprout::uuids::detail::digits<Elem>::table[(u[3]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[4] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[4]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[4] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[5] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[4]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[5]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[5] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash, sprout::uuids::detail::digits<Elem>::table[(u[5]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[6] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[6]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[6] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[7] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[6]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[7]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[7] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash, sprout::uuids::detail::digits<Elem>::table[(u[7]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[8] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[8]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[8] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[9] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[8]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[9]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[9] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::dash, sprout::uuids::detail::digits<Elem>::table[(u[9]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[10] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::dash,
sprout::uuids::detail::digits<Elem>::table[(u[10]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[10] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[11] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[10]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[11]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[11] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[12] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[11]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[12]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[12] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[13] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[12]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[13]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[13] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[14] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[13]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[14]) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[14] >> 4) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[15] >> 4) & 0x0F], sprout::uuids::detail::digits<Elem>::table[(u[14]) & 0x0F],
sprout::uuids::detail::digits<Elem>::table[(u[15]) & 0x0F] sprout::uuids::detail::digits<Elem>::table[(u[15] >> 4) & 0x0F],
}, sprout::uuids::detail::digits<Elem>::table[(u[15]) & 0x0F]
36 );
};
} }
// //
// to_string // to_string