mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-05-10 09:23:30 +00:00
fix string constructor range version
This commit is contained in:
parent
e179cefdac
commit
330e708eff
3 changed files with 136 additions and 36 deletions
|
@ -74,6 +74,10 @@ namespace testspr {
|
||||||
SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(cstr, cstr + 6);
|
SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(cstr, cstr + 6);
|
||||||
TESTSPR_BOTH_ASSERT(s1 == "foobar");
|
TESTSPR_BOTH_ASSERT(s1 == "foobar");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto s1 = sprout::string_t<10>::type(testspr::reduct_input(str1.begin()), testspr::reduct_input(str1.begin() + 6));
|
||||||
|
TESTSPR_BOTH_ASSERT(s1 == "foobar");
|
||||||
|
}
|
||||||
{
|
{
|
||||||
auto s1 = sprout::string_t<10>::type({'f', 'o', 'o', 'b', 'a', 'r'});
|
auto s1 = sprout::string_t<10>::type({'f', 'o', 'o', 'b', 'a', 'r'});
|
||||||
TESTSPR_ASSERT(s1 == "foobar");
|
TESTSPR_ASSERT(s1 == "foobar");
|
||||||
|
|
|
@ -155,36 +155,36 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstIterator s2, std::size_t n) {
|
static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstInputIterator s2, std::size_t n) {
|
||||||
return sprout::tristate_lexicographical_compare(
|
return sprout::tristate_lexicographical_compare(
|
||||||
sprout::ptr_index(s1), sprout::ptr_index(s1, n), char_type(),
|
sprout::ptr_index(s1), sprout::ptr_index(s1, n), char_type(),
|
||||||
s2, s2 + n, char_type(),
|
s2, s2 + n, char_type(),
|
||||||
sprout::detail::char_traits_lt<char_traits>()
|
sprout::detail::char_traits_lt<char_traits>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR int compare(ConstIterator s1, char_type const* s2, std::size_t n) {
|
static SPROUT_CONSTEXPR int compare(ConstInputIterator s1, char_type const* s2, std::size_t n) {
|
||||||
return sprout::tristate_lexicographical_compare(
|
return sprout::tristate_lexicographical_compare(
|
||||||
s1, s1 + n, char_type(),
|
s1, s1 + n, char_type(),
|
||||||
sprout::ptr_index(s2), sprout::ptr_index(s2, n), char_type(),
|
sprout::ptr_index(s2), sprout::ptr_index(s2, n), char_type(),
|
||||||
sprout::detail::char_traits_lt<char_traits>()
|
sprout::detail::char_traits_lt<char_traits>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator1, typename ConstIterator2>
|
template<typename ConstInputIterator1, typename ConstInputIterator2>
|
||||||
static SPROUT_CONSTEXPR int compare(ConstIterator1 s1, ConstIterator2 s2, std::size_t n) {
|
static SPROUT_CONSTEXPR int compare(ConstInputIterator1 s1, ConstInputIterator2 s2, std::size_t n) {
|
||||||
return sprout::tristate_lexicographical_compare(
|
return sprout::tristate_lexicographical_compare(
|
||||||
s1, s1 + n, char_type(),
|
s1, s1 + n, char_type(),
|
||||||
s2, s2 + n, char_type(),
|
s2, s2 + n, char_type(),
|
||||||
sprout::detail::char_traits_lt<char_traits>()
|
sprout::detail::char_traits_lt<char_traits>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) {
|
static SPROUT_CONSTEXPR std::size_t length(ConstInputIterator s) {
|
||||||
return sprout::detail::strlen(s);
|
return sprout::detail::strlen(s);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
static SPROUT_CONSTEXPR ConstInputIterator find(ConstInputIterator s, std::size_t n, char_type const& a) {
|
||||||
return sprout::ptr_unindex(
|
return sprout::ptr_unindex(
|
||||||
sprout::find_if(
|
sprout::find_if(
|
||||||
s, s + n,
|
s, s + n,
|
||||||
|
@ -192,18 +192,18 @@ namespace sprout {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename Iterator, typename ConstIterator>
|
template<typename OutputIterator, typename ConstInputIterator>
|
||||||
static Iterator move(Iterator s1, ConstIterator s2, std::size_t n) {
|
static OutputIterator move(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
|
||||||
std::copy_backward(s2, s2 + n, s1);
|
std::copy_backward(s2, s2 + n, s1);
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
template<typename Iterator, typename ConstIterator>
|
template<typename OutputIterator, typename ConstInputIterator>
|
||||||
static Iterator copy(Iterator s1, ConstIterator s2, std::size_t n) {
|
static OutputIterator copy(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
|
||||||
std::copy(s2, s2 + n, s1);
|
std::copy(s2, s2 + n, s1);
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
template<typename Iterator>
|
template<typename OutputIterator>
|
||||||
static Iterator assign(Iterator s, std::size_t n, char_type a) {
|
static OutputIterator assign(OutputIterator s, std::size_t n, char_type a) {
|
||||||
std::fill(s, s + n, a);
|
std::fill(s, s + n, a);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -238,19 +238,19 @@ namespace sprout {
|
||||||
return found != last;
|
return found != last;
|
||||||
}
|
}
|
||||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s, std::size_t n) {
|
static SPROUT_CONSTEXPR std::size_t length(ConstInputIterator s, std::size_t n) {
|
||||||
return sprout::detail::strlen(s, n);
|
return sprout::detail::strlen(s, n);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
static SPROUT_CONSTEXPR ConstInputIterator find(ConstInputIterator s, std::size_t n, char_type const& a) {
|
||||||
return sprout::find_if(
|
return sprout::find_if(
|
||||||
s, s + n,
|
s, s + n,
|
||||||
sprout::bind2nd(sprout::detail::char_traits_eq<traits_type>(), a)
|
sprout::bind2nd(sprout::detail::char_traits_eq<traits_type>(), a)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename ConstIterator>
|
template<typename ConstInputIterator>
|
||||||
static SPROUT_CONSTEXPR bool is_found(ConstIterator found, ConstIterator last) {
|
static SPROUT_CONSTEXPR bool is_found(ConstInputIterator found, ConstInputIterator last) {
|
||||||
return found != last;
|
return found != last;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
#include <sprout/array/make_array.hpp>
|
#include <sprout/array/make_array.hpp>
|
||||||
#include <sprout/iterator/reverse_iterator.hpp>
|
#include <sprout/iterator/reverse_iterator.hpp>
|
||||||
#include <sprout/iterator/operation.hpp>
|
#include <sprout/iterator/operation.hpp>
|
||||||
|
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
|
||||||
#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>
|
||||||
|
@ -33,10 +35,76 @@
|
||||||
# include <sprout/iterator/index_iterator.hpp>
|
# include <sprout/iterator/index_iterator.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
namespace detail {
|
||||||
|
template<typename Iterator, typename T, std::size_t N>
|
||||||
|
class constant_size_source {
|
||||||
|
private:
|
||||||
|
typedef sprout::array<T, N> array_type;
|
||||||
|
public:
|
||||||
|
typedef typename array_type::size_type size_type;
|
||||||
|
typedef typename array_type::const_reference const_reference;
|
||||||
|
private:
|
||||||
|
array_type arr_;
|
||||||
|
size_type size_;
|
||||||
|
public:
|
||||||
|
SPROUT_CONSTEXPR constant_size_source()
|
||||||
|
: arr_{{}}, size_()
|
||||||
|
{}
|
||||||
|
template<typename... Args>
|
||||||
|
explicit SPROUT_CONSTEXPR constant_size_source(size_type n, Args&&... args)
|
||||||
|
: arr_{{static_cast<T>(sprout::forward<Args>(args))...}}, size_(n)
|
||||||
|
{}
|
||||||
|
SPROUT_CONSTEXPR size_type size() const {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR const_reference operator[](size_type i) const {
|
||||||
|
return arr_[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, std::size_t N, typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
sprout::is_random_access_iterator<RandomAccessIterator>::value,
|
||||||
|
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||||
|
>::type
|
||||||
|
make_constant_size_source(RandomAccessIterator const& first, RandomAccessIterator const& last) {
|
||||||
|
return sprout::distance(first, last);
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N, typename InputIterator, typename... Args>
|
||||||
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
N == sizeof...(Args),
|
||||||
|
sprout::detail::constant_size_source<InputIterator, T, N>
|
||||||
|
>::type
|
||||||
|
make_constant_size_source_impl(InputIterator first, InputIterator last, Args const&... args) {
|
||||||
|
return sprout::detail::constant_size_source<InputIterator, T, N>(sizeof...(args) + (first != last ? 1 : 0), args...);
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N, typename InputIterator, typename... Args>
|
||||||
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
N != sizeof...(Args),
|
||||||
|
sprout::detail::constant_size_source<InputIterator, T, N>
|
||||||
|
>::type
|
||||||
|
make_constant_size_source_impl(InputIterator first, InputIterator last, Args const&... args) {
|
||||||
|
return first != last
|
||||||
|
? sprout::detail::make_constant_size_source_impl<T, N>(sprout::next(first), last, args..., *first)
|
||||||
|
: sprout::detail::constant_size_source<InputIterator, T, N>(sizeof...(args), args...)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N, typename InputIterator>
|
||||||
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
!sprout::is_random_access_iterator<InputIterator>::value,
|
||||||
|
sprout::detail::constant_size_source<InputIterator, T, N>
|
||||||
|
>::type
|
||||||
|
make_constant_size_source(InputIterator const& first, InputIterator const& last) {
|
||||||
|
return sprout::detail::make_constant_size_source_impl<T, N>(first, last);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
struct string_raw_construct_t {};
|
struct string_raw_construct_t {};
|
||||||
struct string_checked_construct_t {};
|
struct string_checked_construct_t {};
|
||||||
|
struct string_range_construct_t {};
|
||||||
|
|
||||||
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 string_construct_access;
|
class string_construct_access;
|
||||||
|
@ -44,13 +112,13 @@ namespace sprout {
|
||||||
template<typename T, std::size_t N, typename Traits>
|
template<typename T, std::size_t N, typename Traits>
|
||||||
class basic_string_impl {
|
class basic_string_impl {
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef typename Traits::char_type value_type;
|
||||||
typedef T& reference;
|
typedef value_type& reference;
|
||||||
typedef T const& const_reference;
|
typedef value_type const& const_reference;
|
||||||
typedef std::size_t size_type;
|
typedef std::size_t size_type;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
typedef T* pointer;
|
typedef value_type* pointer;
|
||||||
typedef T const* const_pointer;
|
typedef value_type const* const_pointer;
|
||||||
typedef Traits traits_type;
|
typedef Traits traits_type;
|
||||||
protected:
|
protected:
|
||||||
value_type elems[N + 1];
|
value_type elems[N + 1];
|
||||||
|
@ -67,7 +135,7 @@ namespace sprout {
|
||||||
String const& str, size_type pos, size_type n
|
String const& str, size_type pos, size_type n
|
||||||
)
|
)
|
||||||
: elems{
|
: elems{
|
||||||
(sprout::math::less(Indexes, n) ? str[Indexes + pos]
|
(sprout::math::less(Indexes, n) ? static_cast<value_type>(str[Indexes + pos])
|
||||||
: value_type()
|
: value_type()
|
||||||
)...
|
)...
|
||||||
}
|
}
|
||||||
|
@ -79,7 +147,7 @@ namespace sprout {
|
||||||
sprout::detail::string_checked_construct_t, String const& str, size_type pos, size_type n
|
sprout::detail::string_checked_construct_t, String const& str, size_type pos, size_type n
|
||||||
)
|
)
|
||||||
: elems{
|
: elems{
|
||||||
(sprout::math::less(Indexes, n) ? str[Indexes + pos]
|
(sprout::math::less(Indexes, n) ? static_cast<value_type>(str[Indexes + pos])
|
||||||
: value_type()
|
: value_type()
|
||||||
)...
|
)...
|
||||||
}
|
}
|
||||||
|
@ -87,13 +155,43 @@ namespace sprout {
|
||||||
: throw std::out_of_range("basic_string<>: index out of range")
|
: throw std::out_of_range("basic_string<>: index out of range")
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
template<typename RandomAccessIterator, typename Size, sprout::index_t... Indexes>
|
||||||
|
SPROUT_CONSTEXPR basic_string_impl(
|
||||||
|
sprout::index_tuple<Indexes...>,
|
||||||
|
sprout::detail::string_range_construct_t, RandomAccessIterator const& str, Size n,
|
||||||
|
std::random_access_iterator_tag*
|
||||||
|
)
|
||||||
|
: elems{
|
||||||
|
(sprout::math::less(Indexes, n) ? static_cast<value_type>(str[Indexes])
|
||||||
|
: value_type()
|
||||||
|
)...
|
||||||
|
}
|
||||||
|
, len(!(N < n) ? n
|
||||||
|
: throw std::out_of_range("basic_string<>: index out of range")
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
template<typename InputIterator, typename Source, sprout::index_t... Indexes>
|
||||||
|
SPROUT_CONSTEXPR basic_string_impl(
|
||||||
|
sprout::index_tuple<Indexes...>,
|
||||||
|
sprout::detail::string_range_construct_t, InputIterator, Source const& str,
|
||||||
|
void*
|
||||||
|
)
|
||||||
|
: elems{
|
||||||
|
(sprout::math::less(Indexes, str.size()) ? static_cast<value_type>(str[Indexes])
|
||||||
|
: value_type()
|
||||||
|
)...
|
||||||
|
}
|
||||||
|
, len(!(N < str.size()) ? str.size()
|
||||||
|
: throw std::out_of_range("basic_string<>: index out of range")
|
||||||
|
)
|
||||||
|
{}
|
||||||
template<typename... Args, sprout::index_t... Indexes>
|
template<typename... Args, sprout::index_t... Indexes>
|
||||||
SPROUT_CONSTEXPR basic_string_impl(
|
SPROUT_CONSTEXPR basic_string_impl(
|
||||||
sprout::index_tuple<Indexes...>,
|
sprout::index_tuple<Indexes...>,
|
||||||
sprout::detail::string_raw_construct_t, size_type n, Args&&... args
|
sprout::detail::string_raw_construct_t, size_type n, Args&&... args
|
||||||
)
|
)
|
||||||
: elems{
|
: elems{
|
||||||
(sprout::math::less(Indexes, n) ? sprout::forward<Args>(args)
|
(sprout::math::less(Indexes, n) ? static_cast<value_type>(sprout::forward<Args>(args))
|
||||||
: value_type()
|
: value_type()
|
||||||
)...
|
)...
|
||||||
}
|
}
|
||||||
|
@ -231,14 +329,12 @@ namespace sprout {
|
||||||
sprout::detail::string_checked_construct_t(), s, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, traits_type::length(s))
|
sprout::detail::string_checked_construct_t(), s, 0, NS_SSCRISK_CEL_OR_SPROUT::min(n, traits_type::length(s))
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
// !!!
|
template<typename InputIterator>
|
||||||
// template<typename InputIterator>
|
SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last)
|
||||||
// SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last);
|
|
||||||
template<typename RandomAccessIterator>
|
|
||||||
SPROUT_CONSTEXPR basic_string(RandomAccessIterator first, RandomAccessIterator last)
|
|
||||||
: impl_type(
|
: impl_type(
|
||||||
sprout::make_index_tuple<N>::make(),
|
sprout::make_index_tuple<N>::make(),
|
||||||
sprout::detail::string_checked_construct_t(), first, 0, sprout::distance(first, last)
|
sprout::detail::string_range_construct_t(), first, sprout::detail::make_constant_size_source<T, N>(first, last),
|
||||||
|
typename sprout::identity<typename std::iterator_traits<InputIterator>::iterator_category*>::type()
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
basic_string(std::initializer_list<value_type> il)
|
basic_string(std::initializer_list<value_type> il)
|
||||||
|
|
Loading…
Add table
Reference in a new issue