add index_tuple/integer_seq

This commit is contained in:
bolero-MURAKAMI 2013-03-31 13:39:26 +09:00
parent 6a78f64feb
commit 331aaa3559
14 changed files with 358 additions and 180 deletions

View file

@ -2,11 +2,15 @@
#define SPROUT_INDEX_TUPLE_HPP #define SPROUT_INDEX_TUPLE_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/integer_seq.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/index_tuple.hpp>
#include <sprout/index_tuple/tuple.hpp> #include <sprout/index_tuple/tuple.hpp>
#include <sprout/index_tuple/make_indexes.hpp> #include <sprout/index_tuple/make_integer_seq.hpp>
#include <sprout/index_tuple/make_index_tuple.hpp>
#include <sprout/index_tuple/integer_range.hpp>
#include <sprout/index_tuple/index_range.hpp> #include <sprout/index_tuple/index_range.hpp>
#include <sprout/index_tuple/integer_n.hpp>
#include <sprout/index_tuple/index_n.hpp> #include <sprout/index_tuple/index_n.hpp>
#include <sprout/index_tuple/pack_indexes.hpp> #include <sprout/index_tuple/make_indexes.hpp>
#endif // #ifndef SPROUT_INDEX_TUPLE_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_HPP

View file

@ -2,74 +2,29 @@
#define SPROUT_INDEX_TUPLE_INDEX_N_HPP #define SPROUT_INDEX_TUPLE_INDEX_N_HPP
#include <cstddef> #include <cstddef>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/integer_n.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp> #include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout { namespace sprout {
// //
// index_n // index_n
// //
namespace detail {
template<typename IndexTuple>
struct index_n_next;
template<sprout::index_t... Indexes>
struct index_n_next<sprout::index_tuple<Indexes...>> {
public:
typedef sprout::index_tuple<Indexes..., Indexes...> type;
};
template<typename IndexTuple, sprout::index_t Tail>
struct index_n_next2;
template<sprout::index_t... Indexes, sprout::index_t Tail>
struct index_n_next2<sprout::index_tuple<Indexes...>, Tail> {
public:
typedef sprout::index_tuple<Indexes..., Indexes..., Tail> type;
};
template<sprout::index_t I, std::size_t N, typename Enable = void>
struct index_n_impl;
template<sprout::index_t I, std::size_t N>
struct index_n_impl<
I, N,
typename std::enable_if<(N == 0)>::type
> {
public:
typedef sprout::index_tuple<> type;
};
template<sprout::index_t I, std::size_t N>
struct index_n_impl<
I, N,
typename std::enable_if<(N == 1)>::type
> {
public:
typedef sprout::index_tuple<I> type;
};
template<sprout::index_t I, std::size_t N>
struct index_n_impl<
I, N,
typename std::enable_if<(N > 1 && N % 2 == 0)>::type
>
: public sprout::detail::index_n_next<
typename sprout::detail::index_n_impl<I, N / 2>::type
>
{};
template<sprout::index_t I, std::size_t N>
struct index_n_impl<
I, N,
typename std::enable_if<(N > 1 && N % 2 == 1)>::type
>
: public sprout::detail::index_n_next2<
typename sprout::detail::index_n_impl<I, N / 2>::type,
I
>
{};
} // namespace detail
template<sprout::index_t I, std::size_t N> template<sprout::index_t I, std::size_t N>
struct index_n struct index_n
: public sprout::detail::make_indexes_helper< : public sprout::detail::make_indexes_helper<
sprout::detail::index_n_impl<I, N> typename sprout::integer_n<sprout::index_t, I, N>::type
::template transfer<sprout::index_tuple<> >::type
>
{};
//
// uindex_n
//
template<sprout::uindex_t I, std::size_t N>
struct uindex_n
: public sprout::detail::make_indexes_helper<
typename sprout::integer_n<sprout::uindex_t, I, N>::type
::template transfer<sprout::uindex_tuple<> >::type
> >
{}; {};
} // namespace sprout } // namespace sprout

View file

@ -2,78 +2,30 @@
#define SPROUT_INDEX_TUPLE_INDEX_RANGE_HPP #define SPROUT_INDEX_TUPLE_INDEX_RANGE_HPP
#include <cstddef> #include <cstddef>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/index_tuple.hpp>
#include <sprout/index_tuple/integer_range.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp> #include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout { namespace sprout {
// //
// index_range // index_range
// //
namespace detail { template<sprout::index_t First, sprout::index_t Last, std::ptrdiff_t Step = 1>
template<typename IndexTuple, sprout::index_t Next>
struct index_range_next;
template<sprout::index_t... Indexes, sprout::index_t Next>
struct index_range_next<sprout::index_tuple<Indexes...>, Next> {
public:
typedef sprout::index_tuple<Indexes..., (Indexes + Next)...> type;
};
template<typename IndexTuple, sprout::index_t Next, sprout::index_t Tail>
struct index_range_next2;
template<sprout::index_t... Indexes, sprout::index_t Next, sprout::index_t Tail>
struct index_range_next2<sprout::index_tuple<Indexes...>, Next, Tail> {
public:
typedef sprout::index_tuple<Indexes..., (Indexes + Next)..., Tail> type;
};
template<sprout::index_t First, sprout::index_t Step, std::size_t N, typename Enable = void>
struct index_range_impl;
template<sprout::index_t First, sprout::index_t Step, std::size_t N>
struct index_range_impl<
First, Step, N,
typename std::enable_if<(N == 0)>::type
> {
public:
typedef sprout::index_tuple<> type;
};
template<sprout::index_t First, sprout::index_t Step, std::size_t N>
struct index_range_impl<
First, Step, N,
typename std::enable_if<(N == 1)>::type
> {
public:
typedef sprout::index_tuple<First> type;
};
template<sprout::index_t First, sprout::index_t Step, std::size_t N>
struct index_range_impl<
First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 0)>::type
>
: public sprout::detail::index_range_next<
typename sprout::detail::index_range_impl<First, Step, N / 2>::type,
First + N / 2 * Step
>
{};
template<sprout::index_t First, sprout::index_t Step, std::size_t N>
struct index_range_impl<
First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 1)>::type
>
: public sprout::detail::index_range_next2<
typename sprout::detail::index_range_impl<First, Step, N / 2>::type,
First + N / 2 * Step,
First + (N - 1) * Step
>
{};
} // namespace detail
template<sprout::index_t First, sprout::index_t Last, sprout::index_t Step = 1>
struct index_range struct index_range
: public sprout::detail::make_indexes_helper< : public sprout::detail::make_indexes_helper<
sprout::detail::index_range_impl< typename sprout::integer_range<sprout::index_t, First, Last, Step>::type
First, Step, ((Last - First) + (Step - 1)) / Step ::template transfer<sprout::index_tuple<> >::type
> >
{};
//
// uindex_range
//
template<sprout::uindex_t First, sprout::uindex_t Last, std::ptrdiff_t Step = 1>
struct uindex_range
: public sprout::detail::make_indexes_helper<
typename sprout::integer_range<sprout::uindex_t, First, Last, Step>::type
::template transfer<sprout::uindex_tuple<> >::type
> >
{}; {};
} // namespace sprout } // namespace sprout

View file

@ -3,26 +3,42 @@
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/integer_seq.hpp>
namespace sprout { namespace sprout {
// //
// index_t // index_t
//
typedef std::ptrdiff_t index_t;
//
// index_tuple // index_tuple
// //
typedef std::ptrdiff_t index_t;
template<sprout::index_t... Indexes> template<sprout::index_t... Indexes>
struct index_tuple { struct index_tuple
: public sprout::integer_seq<sprout::index_t, Indexes...>
{
public: public:
typedef index_tuple type; typedef index_tuple type;
typedef sprout::index_t value_type; template<sprout::index_t... J>
public: struct rebind
SPROUT_STATIC_CONSTEXPR std::size_t size = sizeof...(Indexes); : public index_tuple<J...>
{};
};
//
// uindex_t
// uindex_tuple
//
typedef std::size_t uindex_t;
template<sprout::uindex_t... Indexes>
struct uindex_tuple
: public sprout::integer_seq<sprout::uindex_t, Indexes...>
{
public:
typedef uindex_tuple type;
template<sprout::uindex_t... J>
struct rebind
: public uindex_tuple<J...>
{};
}; };
template<sprout::index_t... Indexes>
SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::index_tuple<Indexes...>::size;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INDEX_TUPLE_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_INDEX_TUPLE_HPP

View file

@ -0,0 +1,73 @@
#ifndef SPROUT_INDEX_TUPLE_INTEGER_N_HPP
#define SPROUT_INDEX_TUPLE_INTEGER_N_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple/integer_seq.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout {
//
// integer_n
//
namespace detail {
template<typename T, typename Seq>
struct integer_n_next_even;
template<typename T, T... Is>
struct integer_n_next_even<T, sprout::integer_seq<T, Is...> >
: public sprout::integer_seq<T, Is..., Is...>
{};
template<typename T, typename Seq, T Tail>
struct integer_n_next_even_odd;
template<typename T, T... Is, T Tail>
struct integer_n_next_even_odd<T, sprout::integer_seq<T, Is...>, Tail>
: public sprout::integer_seq<T, Is..., Is..., Tail>
{};
template<typename T, T I, std::size_t N, typename Enable = void>
struct integer_n_impl;
template<typename T, T I, std::size_t N>
struct integer_n_impl<
T, I, N,
typename std::enable_if<(N == 0)>::type
>
: public sprout::integer_seq<T>
{};
template<typename T, T I, std::size_t N>
struct integer_n_impl<
T, I, N,
typename std::enable_if<(N == 1)>::type
>
: public sprout::integer_seq<T, I>
{};
template<typename T, T I, std::size_t N>
struct integer_n_impl<
T, I, N,
typename std::enable_if<(N > 1 && N % 2 == 0)>::type
>
: public sprout::detail::integer_n_next_even<
T, typename sprout::detail::integer_n_impl<T, I, N / 2>::type
>
{};
template<typename T, T I, std::size_t N>
struct integer_n_impl<
T, I, N,
typename std::enable_if<(N > 1 && N % 2 == 1)>::type
>
: public sprout::detail::integer_n_next_even_odd<
T, typename sprout::detail::integer_n_impl<T, I, N / 2>::type,
I
>
{};
} // namespace detail
template<typename T, T I, std::size_t N>
struct integer_n
: public sprout::detail::make_indexes_helper<
sprout::detail::integer_n_impl<T, I, N>
>
{};
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_N_HPP

View file

@ -0,0 +1,76 @@
#ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP
#define SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple/integer_seq.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout {
//
// integer_range
//
namespace detail {
template<typename T, typename Seq, T Next>
struct integer_range_next_even;
template<typename T, T... Is, T Next>
struct integer_range_next_even<T, sprout::integer_seq<T, Is...>, Next>
: public sprout::integer_seq<T, Is..., (Is + Next)...>
{};
template<typename T, typename Seq, T Next, T Tail>
struct integer_range_next_odd;
template<typename T, T... Is, T Next, T Tail>
struct integer_range_next_odd<T, sprout::integer_seq<T, Is...>, Next, Tail>
: public sprout::integer_seq<T, Is..., (Is + Next)..., Tail>
{};
template<typename T, T First, std::ptrdiff_t Step, std::size_t N, typename Enable = void>
struct integer_range_impl;
template<typename T, T First, std::ptrdiff_t Step, std::size_t N>
struct integer_range_impl<
T, First, Step, N,
typename std::enable_if<(N == 0)>::type
>
: public sprout::integer_seq<T>
{};
template<typename T, T First, std::ptrdiff_t Step, std::size_t N>
struct integer_range_impl<
T, First, Step, N,
typename std::enable_if<(N == 1)>::type
>
: public sprout::integer_seq<T, First>
{};
template<typename T, T First, std::ptrdiff_t Step, std::size_t N>
struct integer_range_impl<
T, First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 0)>::type
>
: public sprout::detail::integer_range_next_even<
T, typename sprout::detail::integer_range_impl<T, First, Step, N / 2>::type,
First + N / 2 * Step
>
{};
template<typename T, T First, std::ptrdiff_t Step, std::size_t N>
struct integer_range_impl<
T, First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 1)>::type
>
: public sprout::detail::integer_range_next_odd<
T, typename sprout::detail::integer_range_impl<T, First, Step, N / 2>::type,
First + N / 2 * Step, First + (N - 1) * Step
>
{};
} // namespace detail
template<typename T, T First, T Last, std::ptrdiff_t Step = 1>
struct integer_range
: public sprout::detail::make_indexes_helper<
sprout::detail::integer_range_impl<
T, First, Step, ((Last - First) + (Step - 1)) / Step
>
>
{};
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP

View file

@ -0,0 +1,32 @@
#ifndef SPROUT_INDEX_TUPLE_INTEGER_SEQ_HPP
#define SPROUT_INDEX_TUPLE_INTEGER_SEQ_HPP
#include <cstddef>
#include <sprout/config.hpp>
namespace sprout {
//
// integer_seq
//
template<typename T, T... Is>
struct integer_seq {
public:
typedef integer_seq type;
template<T... J>
struct rebind
: public integer_seq<T, J...>
{};
public:
typedef T value_type;
template<typename Seq>
struct transfer
: public Seq::template rebind<Is...>
{};
public:
SPROUT_STATIC_CONSTEXPR std::size_t size = sizeof...(Is);
};
template<typename T, T... Is>
SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::integer_seq<T, Is...>::size;
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_SEQ_HPP

View file

@ -0,0 +1,33 @@
#ifndef SPROUT_INDEX_TUPLE_MAKE_INDEX_TUPLE_HPP
#define SPROUT_INDEX_TUPLE_MAKE_INDEX_TUPLE_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/index_tuple/index_tuple.hpp>
#include <sprout/index_tuple/make_integer_seq.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout {
//
// make_index_tuple
//
template<sprout::index_t N>
struct make_index_tuple
: public sprout::detail::make_indexes_helper<
typename sprout::make_integer_seq<sprout::index_t, N>::type
::template transfer<sprout::index_tuple<> >::type
>
{};
//
// make_uindex_tuple
//
template<sprout::uindex_t N>
struct make_uindex_tuple
: public sprout::detail::make_indexes_helper<
typename sprout::make_integer_seq<sprout::uindex_t, N>::type
::template transfer<sprout::uindex_tuple<> >::type
>
{};
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INDEX_TUPLE_HPP

View file

@ -7,10 +7,10 @@ namespace sprout {
// //
// make_indexes // make_indexes
// //
template<typename IndexTupleType> template<typename Seq>
inline SPROUT_CONSTEXPR typename IndexTupleType::type inline SPROUT_CONSTEXPR typename Seq::type
make_indexes() { make_indexes() {
return typename IndexTupleType::type(); return typename Seq::type();
} }
} // namespace sprout } // namespace sprout

View file

@ -0,0 +1,20 @@
#ifndef SPROUT_INDEX_TUPLE_MAKE_INTEGER_SEQ_HPP
#define SPROUT_INDEX_TUPLE_MAKE_INTEGER_SEQ_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple/integer_range.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout {
//
// make_integer_seq
//
template<typename T, T N>
struct make_integer_seq
: public sprout::detail::make_indexes_helper<
sprout::integer_range<T, 0, N>
>
{};
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INTEGER_SEQ_HPP

View file

@ -1,20 +0,0 @@
#ifndef SPROUT_INDEX_TUPLE_PACK_INDEXES_HPP
#define SPROUT_INDEX_TUPLE_PACK_INDEXES_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple/index_range.hpp>
#include <sprout/index_tuple/detail/make_indexes_helper.hpp>
namespace sprout {
//
// pack_indexes
//
template<typename... Args>
struct pack_indexes
: public sprout::detail::make_indexes_helper<
sprout::index_range<0, sizeof...(Args)>
>
{};
} // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_PACK_INDEXES_HPP

View file

@ -5,6 +5,7 @@
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/integer_seq.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/index_tuple.hpp>
namespace std { namespace std {
@ -12,23 +13,52 @@ namespace std {
# pragma clang diagnostic push # pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wmismatched-tags" # pragma clang diagnostic ignored "-Wmismatched-tags"
#endif #endif
//
// tuple_size
//
template<typename T, T... Is>
struct tuple_size<sprout::integer_seq<T, Is...> >
: public std::integral_constant<std::size_t, sizeof...(Is)>
{};
//
// tuple_element
//
template<std::size_t I, typename T, T... Is>
struct tuple_element<I, sprout::integer_seq<T, Is...> > {
static_assert(I < sizeof...(Is), "tuple_element<>: index out of range");
public:
typedef T type;
};
// //
// tuple_size // tuple_size
// //
template<sprout::index_t... Indexes> template<sprout::index_t... Indexes>
struct tuple_size<sprout::index_tuple<Indexes...> > struct tuple_size<sprout::index_tuple<Indexes...> >
: public std::integral_constant<std::size_t, sizeof...(Indexes)> : public std::tuple_size<sprout::integer_seq<sprout::index_t, Indexes...> >
{}; {};
// //
// tuple_element // tuple_element
// //
template<std::size_t I, sprout::index_t... Indexes> template<std::size_t I, sprout::index_t... Indexes>
struct tuple_element<I, sprout::index_tuple<Indexes...> > { struct tuple_element<I, sprout::index_tuple<Indexes...> >
static_assert(I < sizeof...(Indexes), "tuple_element<>: index out of range"); : public std::tuple_element<I, sprout::integer_seq<sprout::index_t, Indexes...> >
public: {};
typedef sprout::index_t type;
}; //
// tuple_size
//
template<sprout::uindex_t... Indexes>
struct tuple_size<sprout::uindex_tuple<Indexes...> >
: public std::tuple_size<sprout::integer_seq<sprout::uindex_t, Indexes...> >
{};
//
// tuple_element
//
template<std::size_t I, sprout::uindex_t... Indexes>
struct tuple_element<I, sprout::uindex_tuple<Indexes...> >
: public std::tuple_element<I, sprout::integer_seq<sprout::uindex_t, Indexes...> >
{};
#if defined(__clang__) #if defined(__clang__)
# pragma clang diagnostic pop # pragma clang diagnostic pop
#endif #endif

View file

@ -11,22 +11,16 @@ namespace sprout {
#if SPROUT_USE_TEMPLATE_ALIASES #if SPROUT_USE_TEMPLATE_ALIASES
// //
// string // string
// wstring
// u16string
// u32string
// //
template<std::size_t N> template<std::size_t N>
using string = sprout::basic_string<char, N>; using string = sprout::basic_string<char, N>;
//
// wstring
//
template<std::size_t N> template<std::size_t N>
using wstring = sprout::basic_string<wchar_t, N>; using wstring = sprout::basic_string<wchar_t, N>;
//
// u16string
//
template<std::size_t N> template<std::size_t N>
using u16string = sprout::basic_string<char16_t, N>; using u16string = sprout::basic_string<char16_t, N>;
//
// u32string
//
template<std::size_t N> template<std::size_t N>
using u32string = sprout::basic_string<char32_t, N>; using u32string = sprout::basic_string<char32_t, N>;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -2,25 +2,38 @@
#define SPROUT_UTILITY_STRING_REF_ALIAS_HPP #define SPROUT_UTILITY_STRING_REF_ALIAS_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/string/char_traits.hpp>
#include <sprout/utility/string_ref/string_ref.hpp> #include <sprout/utility/string_ref/string_ref.hpp>
namespace sprout { namespace sprout {
// //
// string_ref // string_ref
//
typedef sprout::basic_string_ref<char> string_ref;
//
// wstring_ref // wstring_ref
//
typedef sprout::basic_string_ref<wchar_t> wstring_ref;
//
// u16string_ref // u16string_ref
//
typedef sprout::basic_string_ref<char16_t> u16string_ref;
//
// u32string_ref // u32string_ref
// //
typedef sprout::basic_string_ref<char> string_ref;
typedef sprout::basic_string_ref<wchar_t> wstring_ref;
typedef sprout::basic_string_ref<char16_t> u16string_ref;
typedef sprout::basic_string_ref<char32_t> u32string_ref; typedef sprout::basic_string_ref<char32_t> u32string_ref;
//
// string_view
// wstring_view
// u16string_view
// u32string_view
//
typedef sprout::basic_string_ref<char> string_view;
typedef sprout::basic_string_ref<wchar_t> wstring_view;
typedef sprout::basic_string_ref<char16_t> u16string_view;
typedef sprout::basic_string_ref<char32_t> u32string_view;
#if SPROUT_USE_TEMPLATE_ALIASES
//
// basic_string_view
//
template<typename T, typename Traits = sprout::char_traits<T> >
using basic_string_view = sprout::basic_string_ref<T, Traits>;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_UTILITY_STRING_REF_ALIAS_HPP #endif // #ifndef SPROUT_UTILITY_STRING_REF_ALIAS_HPP