mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +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);
|
||||
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'});
|
||||
TESTSPR_ASSERT(s1 == "foobar");
|
||||
|
|
|
@ -155,36 +155,36 @@ namespace sprout {
|
|||
}
|
||||
#endif
|
||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstIterator s2, std::size_t n) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstInputIterator s2, std::size_t n) {
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
sprout::ptr_index(s1), sprout::ptr_index(s1, n), char_type(),
|
||||
s2, s2 + n, char_type(),
|
||||
sprout::detail::char_traits_lt<char_traits>()
|
||||
);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR int compare(ConstIterator s1, char_type const* s2, std::size_t n) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR int compare(ConstInputIterator s1, char_type const* s2, std::size_t n) {
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
s1, s1 + n, char_type(),
|
||||
sprout::ptr_index(s2), sprout::ptr_index(s2, n), char_type(),
|
||||
sprout::detail::char_traits_lt<char_traits>()
|
||||
);
|
||||
}
|
||||
template<typename ConstIterator1, typename ConstIterator2>
|
||||
static SPROUT_CONSTEXPR int compare(ConstIterator1 s1, ConstIterator2 s2, std::size_t n) {
|
||||
template<typename ConstInputIterator1, typename ConstInputIterator2>
|
||||
static SPROUT_CONSTEXPR int compare(ConstInputIterator1 s1, ConstInputIterator2 s2, std::size_t n) {
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
s1, s1 + n, char_type(),
|
||||
s2, s2 + n, char_type(),
|
||||
sprout::detail::char_traits_lt<char_traits>()
|
||||
);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR std::size_t length(ConstInputIterator s) {
|
||||
return sprout::detail::strlen(s);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR ConstInputIterator find(ConstInputIterator s, std::size_t n, char_type const& a) {
|
||||
return sprout::ptr_unindex(
|
||||
sprout::find_if(
|
||||
s, s + n,
|
||||
|
@ -192,18 +192,18 @@ namespace sprout {
|
|||
)
|
||||
);
|
||||
}
|
||||
template<typename Iterator, typename ConstIterator>
|
||||
static Iterator move(Iterator s1, ConstIterator s2, std::size_t n) {
|
||||
template<typename OutputIterator, typename ConstInputIterator>
|
||||
static OutputIterator move(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
|
||||
std::copy_backward(s2, s2 + n, s1);
|
||||
return s1;
|
||||
}
|
||||
template<typename Iterator, typename ConstIterator>
|
||||
static Iterator copy(Iterator s1, ConstIterator s2, std::size_t n) {
|
||||
template<typename OutputIterator, typename ConstInputIterator>
|
||||
static OutputIterator copy(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
|
||||
std::copy(s2, s2 + n, s1);
|
||||
return s1;
|
||||
}
|
||||
template<typename Iterator>
|
||||
static Iterator assign(Iterator s, std::size_t n, char_type a) {
|
||||
template<typename OutputIterator>
|
||||
static OutputIterator assign(OutputIterator s, std::size_t n, char_type a) {
|
||||
std::fill(s, s + n, a);
|
||||
return s;
|
||||
}
|
||||
|
@ -238,19 +238,19 @@ namespace sprout {
|
|||
return found != last;
|
||||
}
|
||||
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s, std::size_t n) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR std::size_t length(ConstInputIterator s, std::size_t n) {
|
||||
return sprout::detail::strlen(s, n);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR ConstInputIterator find(ConstInputIterator s, std::size_t n, char_type const& a) {
|
||||
return sprout::find_if(
|
||||
s, s + n,
|
||||
sprout::bind2nd(sprout::detail::char_traits_eq<traits_type>(), a)
|
||||
);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR bool is_found(ConstIterator found, ConstIterator last) {
|
||||
template<typename ConstInputIterator>
|
||||
static SPROUT_CONSTEXPR bool is_found(ConstInputIterator found, ConstInputIterator last) {
|
||||
return found != last;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
@ -21,6 +22,7 @@
|
|||
#include <sprout/array/make_array.hpp>
|
||||
#include <sprout/iterator/reverse_iterator.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
|
||||
#include <sprout/algorithm/find.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/utility/swap.hpp>
|
||||
|
@ -33,10 +35,76 @@
|
|||
# include <sprout/iterator/index_iterator.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
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 {
|
||||
struct string_raw_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> >
|
||||
class string_construct_access;
|
||||
|
@ -44,13 +112,13 @@ namespace sprout {
|
|||
template<typename T, std::size_t N, typename Traits>
|
||||
class basic_string_impl {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef typename Traits::char_type value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type const* const_pointer;
|
||||
typedef Traits traits_type;
|
||||
protected:
|
||||
value_type elems[N + 1];
|
||||
|
@ -67,7 +135,7 @@ namespace sprout {
|
|||
String const& str, size_type pos, size_type n
|
||||
)
|
||||
: elems{
|
||||
(sprout::math::less(Indexes, n) ? str[Indexes + pos]
|
||||
(sprout::math::less(Indexes, n) ? static_cast<value_type>(str[Indexes + pos])
|
||||
: value_type()
|
||||
)...
|
||||
}
|
||||
|
@ -79,7 +147,7 @@ namespace sprout {
|
|||
sprout::detail::string_checked_construct_t, String const& str, size_type pos, size_type n
|
||||
)
|
||||
: elems{
|
||||
(sprout::math::less(Indexes, n) ? str[Indexes + pos]
|
||||
(sprout::math::less(Indexes, n) ? static_cast<value_type>(str[Indexes + pos])
|
||||
: value_type()
|
||||
)...
|
||||
}
|
||||
|
@ -87,13 +155,43 @@ namespace sprout {
|
|||
: 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>
|
||||
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)
|
||||
(sprout::math::less(Indexes, n) ? static_cast<value_type>(sprout::forward<Args>(args))
|
||||
: 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))
|
||||
)
|
||||
{}
|
||||
// !!!
|
||||
// template<typename InputIterator>
|
||||
// SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last);
|
||||
template<typename RandomAccessIterator>
|
||||
SPROUT_CONSTEXPR basic_string(RandomAccessIterator first, RandomAccessIterator last)
|
||||
template<typename InputIterator>
|
||||
SPROUT_CONSTEXPR basic_string(InputIterator first, InputIterator last)
|
||||
: impl_type(
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue