fix container_traits for pointer type

fix to_string for longer string
This commit is contained in:
bolero-MURAKAMI 2012-12-21 22:35:48 +09:00
parent dd2b9511eb
commit 73cdad232b
14 changed files with 513 additions and 61 deletions

View file

@ -100,4 +100,10 @@
# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 0
#endif // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION
#ifndef SPROUT_CONFIG_DISABLE_SUPPORT_EFFICIENT_ARRAY_ITERATION
# define SPROUT_USE_PTR_INDEX_ITERATOR_IMPLEMENTATION 1
#else // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_EFFICIENT_ARRAY_ITERATION
# define SPROUT_USE_PTR_INDEX_ITERATOR_IMPLEMENTATION 0
#endif // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_EFFICIENT_ARRAY_ITERATION
#endif // #ifndef SPROUT_CONFIG_SUFFIX_HPP

View file

@ -22,6 +22,19 @@ namespace sprout {
range_begin(Container const& cont) {
return cont.begin();
}
template<typename T, std::size_t N>
inline typename sprout::container_traits<T[N]>::iterator
range_begin(T (& arr)[N]) {
typedef typename sprout::container_traits<T[N]>::iterator iterator;
return iterator(arr);
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
range_begin(T const (& arr)[N]) {
typedef typename sprout::container_traits<T const[N]>::const_iterator iterator;
return iterator(arr);
}
} // namespace container_detail
} // namespace sprout
@ -46,12 +59,12 @@ namespace sprout {
template<typename T, std::size_t N>
inline typename sprout::container_traits<T[N]>::iterator
begin(T (& arr)[N]) {
return arr;
return sprout::container_detail::range_begin(arr);
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
begin(T const (& arr)[N]) {
return arr;
return sprout::container_detail::range_begin(arr);
}
//
@ -67,7 +80,7 @@ namespace sprout {
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
cbegin(T const (& arr)[N]) {
return arr;
return sprout::container_detail::range_begin(arr);
}
} // namespace sprout

View file

@ -9,6 +9,9 @@
#include <sprout/type_traits/has_xxx.hpp>
#include <sprout/type_traits/inherit_if_xxx.hpp>
#include <sprout/container/detail/array_like.hpp>
#if SPROUT_USE_PTR_INDEX_ITERATOR_IMPLEMENTATION
# include <sprout/iterator/ptr_index_iterator.hpp>
#endif
namespace sprout {
template<typename Container>
@ -428,8 +431,13 @@ namespace sprout {
struct container_traits_default<T[N]> {
public:
typedef T value_type;
#if SPROUT_USE_PTR_INDEX_ITERATOR_IMPLEMENTATION
typedef sprout::ptr_index_iterator<T> iterator;
typedef sprout::ptr_index_iterator<T const> 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;

View file

@ -22,6 +22,19 @@ namespace sprout {
range_end(Container const& cont) {
return cont.end();
}
template<typename T, std::size_t N>
inline typename sprout::container_traits<T[N]>::iterator
range_end(T (& arr)[N]) {
typedef typename sprout::container_traits<T[N]>::iterator iterator;
return iterator(arr) + N;
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
range_end(T const (& arr)[N]) {
typedef typename sprout::container_traits<T const[N]>::const_iterator iterator;
return iterator(arr) + N;
}
} // namespace container_detail
} // namespace sprout
@ -46,12 +59,12 @@ namespace sprout {
template<typename T, std::size_t N>
inline typename sprout::container_traits<T[N]>::iterator
end(T (& arr)[N]) {
return arr + N;
return sprout::container_detail::range_end(arr);
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
end(T const (& arr)[N]) {
return arr + N;
return sprout::container_detail::range_end(arr);
}
//
@ -67,7 +80,7 @@ namespace sprout {
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<T const[N]>::const_iterator
cend(T const (& arr)[N]) {
return arr + N;
return sprout::container_detail::range_end(arr);
}
} // namespace sprout

View file

@ -5,21 +5,12 @@
#include <sprout/config.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
inline SPROUT_CONSTEXPR std::size_t
strlen_impl(char const* s, std::size_t n) {
return !*s ? n :
sprout::detail::strlen_impl(s + 1, n + 1)
;
}
} // namespace detail
// 7.21.6.3 strlen ŠÖ<C5A0>
inline SPROUT_CONSTEXPR std::size_t
strlen(char const* s) {
return sprout::detail::strlen_impl(s, 0);
return !*s ? 0
: 1 + sprout::strlen(s + 1)
;
}
} // namespace sprout

View file

@ -5,20 +5,11 @@
#include <sprout/config.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
inline SPROUT_CONSTEXPR std::size_t
wcslen_impl(wchar_t const* s, std::size_t n) {
return !*s ? n :
sprout::detail::wcslen_impl(s + 1, n + 1)
;
}
} // namespace detail
inline SPROUT_CONSTEXPR std::size_t
wcslen(wchar_t const* s) {
return sprout::detail::wcslen_impl(s, 0);
return !*s ? 0
: 1 + sprout::wcslen(s + 1)
;
}
} // namespace sprout

View file

@ -20,27 +20,27 @@ namespace sprout {
class index_iterator
: public std::iterator<
std::random_access_iterator_tag,
typename sprout::container_traits<typename std::decay<Container>::type>::value_type,
typename sprout::container_traits<typename std::decay<Container>::type>::difference_type,
typename sprout::container_traits<typename std::remove_reference<Container>::type>::value_type,
typename sprout::container_traits<typename std::remove_reference<Container>::type>::difference_type,
typename std::conditional<
std::is_const<typename std::remove_reference<Container>::type>::value,
typename sprout::container_traits<typename std::decay<Container>::type>::const_pointer,
typename sprout::container_traits<typename std::decay<Container>::type>::pointer
typename sprout::container_traits<typename std::remove_reference<Container>::type>::const_pointer,
typename sprout::container_traits<typename std::remove_reference<Container>::type>::pointer
>::type,
typename std::conditional<
std::is_const<typename std::remove_reference<Container>::type>::value,
typename sprout::container_traits<typename std::decay<Container>::type>::const_reference,
typename sprout::container_traits<typename std::decay<Container>::type>::reference
typename sprout::container_traits<typename std::remove_reference<Container>::type>::const_reference,
typename sprout::container_traits<typename std::remove_reference<Container>::type>::reference
>::type
>
{
public:
typedef Container container_type;
typedef typename sprout::container_traits<typename std::decay<container_type>::type> traits_type;
typedef typename sprout::container_traits<typename std::remove_reference<container_type>::type> traits_type;
typedef typename std::conditional<
std::is_reference<container_type>::value,
typename std::decay<container_type>::type const&,
typename std::decay<container_type>::type const
typename std::remove_reference<container_type>::type const&,
typename std::remove_reference<container_type>::type const
>::type const_container_type;
private:
typedef std::iterator<
@ -58,6 +58,7 @@ namespace sprout {
typename traits_type::reference
>::type
> base_type;
typedef sprout::value_holder<container_type> holder_type;
public:
typedef typename base_type::iterator_category iterator_category;
typedef typename base_type::value_type value_type;
@ -66,10 +67,10 @@ namespace sprout {
typedef typename base_type::reference reference;
typedef typename traits_type::size_type size_type;
private:
sprout::value_holder<container_type> holder_;
holder_type holder_;
size_type index_;
private:
SPROUT_CONSTEXPR index_iterator(sprout::value_holder<container_type> const& r, size_type index)
SPROUT_CONSTEXPR index_iterator(holder_type const& r, size_type index)
: holder_(r)
, index_(index)
{}
@ -79,13 +80,23 @@ namespace sprout {
, index_()
{}
index_iterator(index_iterator const&) = default;
SPROUT_CONSTEXPR index_iterator(typename sprout::value_holder<container_type>::param_type p, size_type index)
explicit SPROUT_CONSTEXPR index_iterator(typename holder_type::param_type p)
: holder_(p)
, index_(0)
{}
SPROUT_CONSTEXPR index_iterator(typename holder_type::param_type p, size_type index)
: holder_(p)
, index_(index)
{}
operator index_iterator<const_container_type>() const {
return index_iterator<const_container_type>(holder_.get(), index_);
}
SPROUT_CONSTEXPR typename holder_type::mutable_or_const_reference base() const {
return holder_.get();
}
SPROUT_CONSTEXPR size_type index() const {
return index_;
}
SPROUT_CONSTEXPR index_iterator next() const {
return index_iterator(holder_, index_ + 1);
}

View file

@ -0,0 +1,286 @@
#ifndef SPROUT_ITERATOR_PTR_INDEX_ITERATOR_HPP
#define SPROUT_ITERATOR_PTR_INDEX_ITERATOR_HPP
#include <iterator>
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp>
#include <sprout/iterator/distance.hpp>
#include <sprout/utility/swap.hpp>
namespace sprout {
//
// ptr_index_iterator
//
template<typename T>
class ptr_index_iterator
: public std::iterator<
typename std::iterator_traits<T*>::iterator_category,
typename std::iterator_traits<T*>::value_type,
typename std::iterator_traits<T*>::difference_type,
typename std::iterator_traits<T*>::pointer,
typename std::iterator_traits<T*>::reference
>
{
public:
typedef T type;
private:
typedef std::iterator<
typename std::iterator_traits<T*>::iterator_category,
typename std::iterator_traits<T*>::value_type,
typename std::iterator_traits<T*>::difference_type,
typename std::iterator_traits<T*>::pointer,
typename std::iterator_traits<T*>::reference
> base_type;
public:
typedef typename base_type::iterator_category iterator_category;
typedef typename base_type::value_type value_type;
typedef typename base_type::difference_type difference_type;
typedef typename base_type::pointer pointer;
typedef typename base_type::reference reference;
typedef typename std::remove_pointer<pointer>::type const* const_pointer;
private:
pointer p_;
difference_type index_;
public:
SPROUT_CONSTEXPR ptr_index_iterator()
: p_()
, index_()
{}
ptr_index_iterator(ptr_index_iterator const&) = default;
explicit SPROUT_CONSTEXPR ptr_index_iterator(pointer p)
: p_(p)
, index_(0)
{}
SPROUT_CONSTEXPR ptr_index_iterator(pointer p, difference_type index)
: p_(p)
, index_(index)
{}
operator ptr_index_iterator<const_pointer>() const {
return ptr_index_iterator<const_pointer>(p_, index_);
}
SPROUT_CONSTEXPR pointer base() const {
return p_;
}
SPROUT_CONSTEXPR difference_type index() const {
return index_;
}
SPROUT_CONSTEXPR pointer ptr() const {
return p_ + index_;
}
SPROUT_CONSTEXPR ptr_index_iterator next() const {
return ptr_index_iterator(p_, index_ + 1);
}
SPROUT_CONSTEXPR ptr_index_iterator prev() const {
return ptr_index_iterator(p_, index_ - 1);
}
void swap(ptr_index_iterator& other)
SPROUT_NOEXCEPT
{
sprout::swap(p_, other.p_);
sprout::swap(index_, other.index_);
}
friend SPROUT_CONSTEXPR bool operator==(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return lhs.index_ == rhs.index_;
}
friend SPROUT_CONSTEXPR bool operator!=(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return !(lhs == rhs);
}
friend SPROUT_CONSTEXPR bool operator<(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return lhs.index_ < rhs.index_;
}
friend SPROUT_CONSTEXPR bool operator>(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return rhs < lhs;
}
friend SPROUT_CONSTEXPR bool operator<=(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return !(rhs < lhs);
}
friend SPROUT_CONSTEXPR bool operator>=(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return !(lhs < rhs);
}
SPROUT_CONSTEXPR reference operator*() const {
return p_[index_];
}
SPROUT_CONSTEXPR pointer operator->() const {
return p_ + index_;
}
ptr_index_iterator& operator++() {
ptr_index_iterator temp(next());
temp.swap(*this);
return *this;
}
ptr_index_iterator operator++(int) {
ptr_index_iterator result(*this);
++*this;
return result;
}
ptr_index_iterator& operator--() {
ptr_index_iterator temp(prev());
temp.swap(*this);
return *this;
}
ptr_index_iterator operator--(int) {
ptr_index_iterator result(*this);
--*this;
return result;
}
SPROUT_CONSTEXPR ptr_index_iterator operator+(difference_type n) const {
return ptr_index_iterator(p_, index_ + n);
}
SPROUT_CONSTEXPR ptr_index_iterator operator-(difference_type n) const {
return ptr_index_iterator(p_, index_ - n);
}
ptr_index_iterator& operator+=(difference_type n) {
ptr_index_iterator temp(p_, index_ + n);
temp.swap(*this);
return *this;
}
ptr_index_iterator& operator-=(difference_type n) {
ptr_index_iterator temp(p_, index_ - n);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return p_[index_ + n];
}
friend SPROUT_CONSTEXPR difference_type operator-(ptr_index_iterator const& lhs, ptr_index_iterator const& rhs) {
return lhs.index_ - rhs.index_;
}
friend SPROUT_CONSTEXPR ptr_index_iterator operator+(difference_type n, ptr_index_iterator const& it) {
return it + n;
}
};
//
// swap
//
template<typename T>
inline void
swap(sprout::ptr_index_iterator<T>& lhs, sprout::ptr_index_iterator<T>& rhs)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
//
// make_ptr_index_iterator
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
make_ptr_index_iterator(T* p) {
return sprout::ptr_index_iterator<T>(p);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
make_ptr_index_iterator(T* p, typename sprout::ptr_index_iterator<T>::difference_type index) {
return sprout::ptr_index_iterator<T>(p, index);
}
//
// as_iterator
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
as_iterator(T* p) {
return sprout::make_ptr_index_iterator(p);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
as_iterator(T* p, typename std::iterator_traits<T*>::difference_type n) {
return sprout::make_ptr_index_iterator(p, n);
}
template<typename Iterator>
inline SPROUT_CONSTEXPR Iterator
as_iterator(Iterator const& it) {
return it;
}
template<typename Iterator>
inline SPROUT_CONSTEXPR Iterator
as_iterator(Iterator const& it, typename std::iterator_traits<Iterator>::difference_type n) {
return sprout::next(it, n);
}
//
// as_iterator_base
//
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::ptr_index_iterator<T>::pointer
as_iterator_base(sprout::ptr_index_iterator<T> const& it) {
return it.ptr();
}
template<typename Iterator>
inline SPROUT_CONSTEXPR Iterator
as_iterator_base(Iterator const& it) {
return it;
}
//
// is_ptr_index_iterator
//
template<typename T>
struct is_ptr_index_iterator
: public std::false_type
{};
template<typename T>
struct is_ptr_index_iterator<T const>
: public sprout::is_ptr_index_iterator<T>
{};
template<typename T>
struct is_ptr_index_iterator<T const volatile>
: public sprout::is_ptr_index_iterator<T>
{};
template<typename T>
struct is_ptr_index_iterator<sprout::ptr_index_iterator<T> >
: public std::true_type
{};
//
// iterator_distance
//
template<typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<sprout::ptr_index_iterator<T> >::difference_type
iterator_distance(sprout::ptr_index_iterator<T> first, sprout::ptr_index_iterator<T> last) {
return last - first;
}
//
// iterator_next
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
iterator_next(sprout::ptr_index_iterator<T> const& it) {
return it.next();
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
iterator_next(
sprout::ptr_index_iterator<T> const& it,
typename sprout::ptr_index_iterator<T>::difference_type n
)
{
return it + n;
}
//
// iterator_prev
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
iterator_prev(sprout::ptr_index_iterator<T> const& it) {
return it.prev();
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::ptr_index_iterator<T>
iterator_prev(
sprout::ptr_index_iterator<T> const& it,
typename sprout::ptr_index_iterator<T>::difference_type n
)
{
return it - n;
}
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_PTR_INDEX_ITERATOR_HPP

View file

@ -3,6 +3,7 @@
#include <sprout/config.hpp>
#include <sprout/iterator/index_iterator.hpp>
#include <sprout/iterator/ptr_index_iterator.hpp>
#include <sprout/iterator/value_iterator.hpp>
#include <sprout/iterator/counting_iterator.hpp>
#include <sprout/iterator/generator_iterator.hpp>

View file

@ -5,6 +5,10 @@
#include <algorithm>
#include <string>
#include <sprout/config.hpp>
#include <sprout/functional/bind2nd.hpp>
#include <sprout/iterator/ptr_index_iterator.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
//
@ -20,6 +24,19 @@ namespace sprout {
typedef typename impl_type::off_type off_type;
typedef typename impl_type::pos_type pos_type;
typedef typename impl_type::state_type state_type;
private:
struct eq_ {
public:
SPROUT_CONSTEXPR bool operator()(char_type c1, char_type c2) const SPROUT_NOEXCEPT {
return eq(c1, c2);
}
};
private:
static SPROUT_CONSTEXPR char_type const* find_impl(char_type const* found, char_type const* last) {
return found == last ? nullptr
: found
;
}
public:
static void assign(char_type& c1, char_type const& c2) SPROUT_NOEXCEPT {
impl_type::assign(c1, c2);
@ -43,10 +60,15 @@ namespace sprout {
;
}
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
return !n ? nullptr
: eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
return find_impl(
sprout::as_iterator_base(
NS_SSCRISK_CEL_OR_SPROUT::find_if(
sprout::as_iterator(s), sprout::as_iterator(s, n),
sprout::bind2nd(eq_(), a)
)
),
s + n
);
}
static char_type* move(char_type* s1, char_type const* s2, std::size_t n) {
return impl_type::move(s1, s2, n);
@ -105,10 +127,12 @@ namespace sprout {
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
return !n ? s
: eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
return sprout::as_iterator_base(
NS_SSCRISK_CEL_OR_SPROUT::find_if(
s, s + n,
sprout::bind2nd(eq_(), a)
)
);
}
template<typename Iterator, typename ConstIterator>
static Iterator move(Iterator s1, ConstIterator s2, std::size_t n) {
@ -140,23 +164,45 @@ namespace sprout {
typedef typename traits_type::off_type off_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::state_type state_type;
private:
struct eq_ {
public:
SPROUT_CONSTEXPR bool operator()(char_type c1, char_type c2) const SPROUT_NOEXCEPT {
return traits_type::eq(c1, c2);
}
};
public:
static SPROUT_CONSTEXPR std::size_t length(char_type const* s, std::size_t n) {
return NS_SSCRISK_CEL_OR_SPROUT::distance(
sprout::as_iterator(s),
find(sprout::as_iterator(s), n, char_type())
);
}
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
return !n ? s
: traits_type::eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
return sprout::as_iterator_base(
NS_SSCRISK_CEL_OR_SPROUT::find_if(
sprout::as_iterator(s), sprout::as_iterator(s, n),
sprout::bind2nd(eq_(), a)
)
);
}
static SPROUT_CONSTEXPR bool is_found(char_type const* found, char_type const* last) {
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) {
return NS_SSCRISK_CEL_OR_SPROUT::distance(
s,
find(s, n, char_type())
);
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
return !n ? s
: traits_type::eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
return NS_SSCRISK_CEL_OR_SPROUT::find_if(
s, s + n,
sprout::bind2nd(eq_(), a)
);
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR bool is_found(ConstIterator found, ConstIterator last) {

View file

@ -126,17 +126,19 @@ namespace sprout {
template<typename T, std::size_t N, typename Traits, std::size_t M>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N + (M - 1), Traits>
operator+(sprout::basic_string<T, N, Traits> const& lhs, T const (& rhs)[M]) {
typedef sprout::char_traits_helper<Traits> traits_type;
return sprout::detail::string_concat(
lhs, lhs.size(),
rhs, sprout::char_traits<T>::length(rhs),
rhs, traits_type::length(rhs, M - 1),
sprout::index_range<0, N + (M - 1)>::make()
);
}
template<typename T, std::size_t N, typename Traits, std::size_t M>
inline SPROUT_CONSTEXPR sprout::basic_string<T, (M - 1) + N, Traits>
operator+(T const (& lhs)[M], sprout::basic_string<T, N, Traits> const& rhs) {
typedef sprout::char_traits_helper<Traits> traits_type;
return sprout::detail::string_concat(
lhs, sprout::char_traits<T>::length(lhs),
lhs, traits_type::length(lhs, M - 1),
rhs, rhs.size(),
sprout::index_range<0, (M - 1) + N>::make()
);

View file

@ -874,7 +874,8 @@ namespace sprout {
template<typename T, std::size_t N, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::basic_string<T, N - 1>
to_string_impl(T const(& arr)[N], sprout::index_tuple<Indexes...>) {
return to_string_impl_1(arr, sprout::char_traits<T>::length(arr), sprout::index_tuple<Indexes...>());
typedef sprout::char_traits_helper<sprout::char_traits<T> > traits_type;
return to_string_impl_1(arr, traits_type::length(arr, N - 1), sprout::index_tuple<Indexes...>());
}
} // namespace detail
//

View file

@ -8,6 +8,7 @@
#include <sprout/variant/get.hpp>
#include <sprout/variant/static_visitor.hpp>
#include <sprout/variant/static_variant_visitor.hpp>
#include <sprout/variant/as_visitor.hpp>
#include <sprout/variant/as_variant_visitor.hpp>
#include <sprout/variant/visitor_result.hpp>
#include <sprout/variant/apply_visitor.hpp>

View file

@ -0,0 +1,82 @@
#ifndef SPROUT_VARIANT_AS_VISITOR_HPP
#define SPROUT_VARIANT_AS_VISITOR_HPP
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/lvalue_forward.hpp>
#include <sprout/utility/value_holder.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/variant/static_visitor.hpp>
#include <sprout/functional/type_traits/has_type.hpp>
#include <sprout/functional/type_traits/weak_result_type.hpp>
namespace sprout {
namespace detail {
template<typename T, typename = void>
struct result_type_or_void;
template<typename T>
struct result_type_or_void<
T,
typename std::enable_if<sprout::has_result_type<sprout::weak_result_type<T> >::value>::type
> {
public:
typedef typename sprout::weak_result_type<T>::result_type type;
};
template<typename T>
struct result_type_or_void<
T,
typename std::enable_if<!sprout::has_result_type<sprout::weak_result_type<T> >::value>::type
> {
public:
typedef void type;
};
} // namespace detail
//
// visitor_wrapper
//
template<
typename Visitor,
typename R = typename sprout::detail::result_type_or_void<Visitor>::type
>
class visitor_wrapper
: public sprout::static_visitor<R>
{
public:
typedef Visitor visitor_type;
typedef sprout::value_holder<visitor_type&> holder_type;
private:
holder_type v_;
public:
SPROUT_CONSTEXPR explicit visitor_wrapper(typename holder_type::param_type v)
: v_(v)
{}
template<typename T>
SPROUT_CONSTEXPR auto operator()(T&& t)
-> decltype(std::declval<holder_type const>().get()(sprout::forward<T>(t))) const
{
return v_.get()(sprout::forward<T>(t));
}
};
//
// as_visitor
//
template<typename Visitor>
inline SPROUT_CONSTEXPR sprout::visitor_wrapper<typename std::remove_reference<typename sprout::lvalue_reference<Visitor>::type>::type>
as_visitor(Visitor&& visitor) {
typedef sprout::visitor_wrapper<typename std::remove_reference<typename sprout::lvalue_reference<Visitor>::type>::type> type;
return type(sprout::lvalue_forward<Visitor>(visitor));
}
template<typename R, typename Visitor>
inline SPROUT_CONSTEXPR sprout::visitor_wrapper<typename std::remove_reference<typename sprout::lvalue_reference<Visitor>::type>::type, R>
as_visitor(Visitor&& visitor) {
typedef sprout::visitor_wrapper<typename std::remove_reference<typename sprout::lvalue_reference<Visitor>::type>::type, R> type;
return type(sprout::lvalue_forward<Visitor>(visitor));
}
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_AS_VISITOR_HPP