mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
sprout/variant.hpp 追加
sprout/type.hpp 追加
This commit is contained in:
parent
488df1e685
commit
b6bf03c4ed
30 changed files with 905 additions and 102 deletions
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/tuple/tuple.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/tuple_comparison.hpp>
|
#include <sprout/tuple/traits.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_TUPLE_HPP
|
#endif // #ifndef SPROUT_TUPLE_HPP
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/index_tuple.hpp>
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/tuple/traits.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/functions.hpp>
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/operation/append_back.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
|
@ -14,25 +15,9 @@ namespace sprout {
|
||||||
// append_back
|
// append_back
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename InputTuple>
|
template<typename Tuple, typename InputTuple>
|
||||||
struct append_back {
|
struct append_back
|
||||||
private:
|
: public sprout::types::append_back<Tuple, InputTuple>
|
||||||
template<typename IndexTuple1, typename IndexTuple2>
|
|
||||||
struct apply_impl;
|
|
||||||
template<std::ptrdiff_t... Indexes1, std::ptrdiff_t... Indexes2>
|
|
||||||
struct apply_impl<sprout::index_tuple<Indexes1...>, sprout::index_tuple<Indexes2...> >
|
|
||||||
: public sprout::tuples::rebind_types<
|
|
||||||
Tuple
|
|
||||||
>::template apply<
|
|
||||||
typename sprout::tuples::tuple_element<Indexes1, Tuple>::type...,
|
|
||||||
typename sprout::tuples::tuple_element<Indexes2, InputTuple>::type...
|
|
||||||
>
|
|
||||||
{};
|
{};
|
||||||
public:
|
|
||||||
typedef typename apply_impl<
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type,
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<InputTuple>::value>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
} // namespace result_of
|
} // namespace result_of
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/index_tuple.hpp>
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/tuple/traits.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/functions.hpp>
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/operation/append_front.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
|
@ -14,25 +15,9 @@ namespace sprout {
|
||||||
// append_front
|
// append_front
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename InputTuple>
|
template<typename Tuple, typename InputTuple>
|
||||||
struct append_front {
|
struct append_front
|
||||||
private:
|
: public sprout::types::append_front<Tuple, InputTuple>
|
||||||
template<typename IndexTuple1, typename IndexTuple2>
|
|
||||||
struct apply_impl;
|
|
||||||
template<std::ptrdiff_t... Indexes1, std::ptrdiff_t... Indexes2>
|
|
||||||
struct apply_impl<sprout::index_tuple<Indexes1...>, sprout::index_tuple<Indexes2...> >
|
|
||||||
: public sprout::tuples::rebind_types<
|
|
||||||
Tuple
|
|
||||||
>::template apply<
|
|
||||||
typename sprout::tuples::tuple_element<Indexes2, InputTuple>::type...,
|
|
||||||
typename sprout::tuples::tuple_element<Indexes1, Tuple>::type...
|
|
||||||
>
|
|
||||||
{};
|
{};
|
||||||
public:
|
|
||||||
typedef typename apply_impl<
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type,
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<InputTuple>::value>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
} // namespace result_of
|
} // namespace result_of
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/index_tuple.hpp>
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/tuple/traits.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/functions.hpp>
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/operation/push_back.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
|
@ -14,24 +15,9 @@ namespace sprout {
|
||||||
// push_back
|
// push_back
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename T>
|
template<typename Tuple, typename T>
|
||||||
struct push_back {
|
struct push_back
|
||||||
private:
|
: public sprout::types::push_back<Tuple, T>
|
||||||
template<typename IndexTuple>
|
|
||||||
struct apply_impl;
|
|
||||||
template<std::ptrdiff_t... Indexes>
|
|
||||||
struct apply_impl<sprout::index_tuple<Indexes...>>
|
|
||||||
: public sprout::tuples::rebind_types<
|
|
||||||
Tuple
|
|
||||||
>::template apply<
|
|
||||||
typename sprout::tuples::tuple_element<Indexes, Tuple>::type...,
|
|
||||||
T
|
|
||||||
>
|
|
||||||
{};
|
{};
|
||||||
public:
|
|
||||||
typedef typename apply_impl<
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
} // namespace result_of
|
} // namespace result_of
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/index_tuple.hpp>
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/tuple/traits.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/functions.hpp>
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/operation/push_front.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
|
@ -14,24 +15,9 @@ namespace sprout {
|
||||||
// push_front
|
// push_front
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename T>
|
template<typename Tuple, typename T>
|
||||||
struct push_front {
|
struct push_front
|
||||||
private:
|
: public sprout::types::push_front<Tuple, T>
|
||||||
template<typename IndexTuple>
|
|
||||||
struct apply_impl;
|
|
||||||
template<std::ptrdiff_t... Indexes>
|
|
||||||
struct apply_impl<sprout::index_tuple<Indexes...>>
|
|
||||||
: public sprout::tuples::rebind_types<
|
|
||||||
Tuple
|
|
||||||
>::template apply<
|
|
||||||
T,
|
|
||||||
typename sprout::tuples::tuple_element<Indexes, Tuple>::type...
|
|
||||||
>
|
|
||||||
{};
|
{};
|
||||||
public:
|
|
||||||
typedef typename apply_impl<
|
|
||||||
typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
} // namespace result_of
|
} // namespace result_of
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/tuple/tuple.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
|
@ -24,20 +25,9 @@ namespace sprout {
|
||||||
// rebind_types
|
// rebind_types
|
||||||
//
|
//
|
||||||
template<typename Tuple>
|
template<typename Tuple>
|
||||||
struct rebind_types {
|
struct rebind_types
|
||||||
public:
|
: public sprout::types::rebind_types<Tuple>
|
||||||
template<typename... Types>
|
{};
|
||||||
struct apply;
|
|
||||||
};
|
|
||||||
template<typename... Ts>
|
|
||||||
struct rebind_types<sprout::tuples::tuple<Ts...> > {
|
|
||||||
public:
|
|
||||||
template<typename... Types>
|
|
||||||
struct apply {
|
|
||||||
public:
|
|
||||||
typedef sprout::tuples::tuple<Types...> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// clone_functor
|
// clone_functor
|
||||||
|
@ -93,7 +83,6 @@ namespace sprout {
|
||||||
} // namespace tuples
|
} // namespace tuples
|
||||||
|
|
||||||
using sprout::tuples::tuple_traits;
|
using sprout::tuples::tuple_traits;
|
||||||
using sprout::tuples::rebind_types;
|
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_TUPLE_TRAITS_HPP
|
#endif // #ifndef SPROUT_TUPLE_TRAITS_HPP
|
||||||
|
|
|
@ -229,7 +229,7 @@ namespace sprout {
|
||||||
: inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
: inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
||||||
{}
|
{}
|
||||||
// tuple assignment
|
// tuple assignment
|
||||||
tuple& operator=(const tuple& rhs) {
|
tuple& operator=(tuple const& rhs) {
|
||||||
static_cast<inherited_type&>(*this) = rhs;
|
static_cast<inherited_type&>(*this) = rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ namespace sprout {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// tuple swap
|
// tuple swap
|
||||||
void swap(tuple& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(other.swap(other))) {
|
void swap(tuple& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(inherited_type::swap(other))) {
|
||||||
inherited_type::swap(other);
|
inherited_type::swap(other);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -426,4 +426,6 @@ namespace sprout {
|
||||||
using sprout::tuples::get;
|
using sprout::tuples::get;
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
|
#include <sprout/tuple/tuple_comparison.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_TUPLE_TUPLE_HPP
|
#endif // #ifndef SPROUT_TUPLE_TUPLE_HPP
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace sprout {
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator==(
|
SPROUT_CONSTEXPR inline bool operator==(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
@ -62,7 +62,7 @@ namespace sprout {
|
||||||
>::eq(lhs, rhs);
|
>::eq(lhs, rhs);
|
||||||
}
|
}
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator<(
|
SPROUT_CONSTEXPR inline bool operator<(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
@ -78,7 +78,7 @@ namespace sprout {
|
||||||
>::less(lhs, rhs);
|
>::less(lhs, rhs);
|
||||||
}
|
}
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator!=(
|
SPROUT_CONSTEXPR inline bool operator!=(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
@ -86,7 +86,7 @@ namespace sprout {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator>(
|
SPROUT_CONSTEXPR inline bool operator>(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
@ -94,7 +94,7 @@ namespace sprout {
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator<=(
|
SPROUT_CONSTEXPR inline bool operator<=(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
@ -102,7 +102,7 @@ namespace sprout {
|
||||||
return !(rhs < lhs);
|
return !(rhs < lhs);
|
||||||
}
|
}
|
||||||
template<typename... TTypes, typename... UTypes>
|
template<typename... TTypes, typename... UTypes>
|
||||||
bool SPROUT_CONSTEXPR inline operator>=(
|
SPROUT_CONSTEXPR inline bool operator>=(
|
||||||
sprout::tuples::tuple<TTypes...> const& lhs,
|
sprout::tuples::tuple<TTypes...> const& lhs,
|
||||||
sprout::tuples::tuple<UTypes...> const& rhs
|
sprout::tuples::tuple<UTypes...> const& rhs
|
||||||
)
|
)
|
||||||
|
|
11
sprout/type.hpp
Normal file
11
sprout/type.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef SPROUT_TYPE_HPP
|
||||||
|
#define SPROUT_TYPE_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/type_tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
#include <sprout/type/algorithm.hpp>
|
||||||
|
#include <sprout/type/operation.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_HPP
|
7
sprout/type/algorithm.hpp
Normal file
7
sprout/type/algorithm.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef SPROUT_TYPE_ALGORITHM_HPP
|
||||||
|
#define SPROUT_TYPE_ALGORITHM_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/algorithm/find_index.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ALGORITHM_HPP
|
49
sprout/type/algorithm/find_index.hpp
Normal file
49
sprout/type/algorithm/find_index.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef SPROUT_TYPE_ALGORITHM_FIND_INDEX_HPP
|
||||||
|
#define SPROUT_TYPE_ALGORITHM_FIND_INDEX_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
namespace detail {
|
||||||
|
template<typename Tuple, typename T, std::size_t I, typename = void>
|
||||||
|
struct find_index_impl;
|
||||||
|
template<typename Tuple, typename T, std::size_t I>
|
||||||
|
struct find_index_impl<
|
||||||
|
Tuple,
|
||||||
|
T,
|
||||||
|
I,
|
||||||
|
typename std::enable_if<
|
||||||
|
I == sprout::types::tuple_size<Tuple>::value
|
||||||
|
|| std::is_same<typename sprout::types::tuple_element<I, Tuple>::type, T>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
: public std::integral_constant<std::size_t, I>
|
||||||
|
{};
|
||||||
|
template<typename Tuple, typename T, std::size_t I>
|
||||||
|
struct find_index_impl<
|
||||||
|
Tuple,
|
||||||
|
T,
|
||||||
|
I,
|
||||||
|
typename std::enable_if<
|
||||||
|
I != sprout::types::tuple_size<Tuple>::value
|
||||||
|
&& !std::is_same<typename sprout::types::tuple_element<I, Tuple>::type, T>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
: public sprout::types::detail::find_index_impl<Tuple, T, I + 1>
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
//
|
||||||
|
// find_index
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename T>
|
||||||
|
struct find_index
|
||||||
|
: public sprout::types::detail::find_index_impl<Tuple, T, 0>
|
||||||
|
{};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ALGORITHM_FIND_INDEX_HPP
|
9
sprout/type/iterator.hpp
Normal file
9
sprout/type/iterator.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef SPROUT_TYPE_ITERATOR_HPP
|
||||||
|
#define SPROUT_TYPE_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/iterator/next.hpp>
|
||||||
|
#include <sprout/type/iterator/prev.hpp>
|
||||||
|
#include <sprout/type/iterator/deref.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ITERATOR_HPP
|
19
sprout/type/iterator/deref.hpp
Normal file
19
sprout/type/iterator/deref.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef SPROUT_TYPE_ITERATOR_DEREF_HPP
|
||||||
|
#define SPROUT_TYPE_ITERATOR_DEREF_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// deref
|
||||||
|
//
|
||||||
|
template<typename Iterator>
|
||||||
|
struct deref {
|
||||||
|
public:
|
||||||
|
typedef typename Iterator::type type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ITERATOR_DEREF_HPP
|
91
sprout/type/iterator/index_iterator.hpp
Normal file
91
sprout/type/iterator/index_iterator.hpp
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef SPROUT_TYPE_ITERATOR_INDEX_ITERATOR_HPP
|
||||||
|
#define SPROUT_TYPE_ITERATOR_INDEX_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/void.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
//
|
||||||
|
// index_iterator_impl
|
||||||
|
//
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index, typename = void>
|
||||||
|
struct index_iterator_impl;
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator_impl<
|
||||||
|
Tuple,
|
||||||
|
Index,
|
||||||
|
typename std::enable_if<
|
||||||
|
sprout::types::tuple_size<Tuple>::value == 0
|
||||||
|
|| (Index < 0)
|
||||||
|
|| (Index > sprout::types::tuple_size<Tuple>::value)
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef sprout::types::void_ type;
|
||||||
|
typedef sprout::types::void_ next;
|
||||||
|
typedef sprout::types::void_ prev;
|
||||||
|
};
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator_impl<
|
||||||
|
Tuple,
|
||||||
|
Index,
|
||||||
|
typename std::enable_if<
|
||||||
|
sprout::types::tuple_size<Tuple>::value != 0
|
||||||
|
&& Index == 0
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
|
||||||
|
typedef sprout::types::index_iterator<Tuple, Index + 1> next;
|
||||||
|
typedef sprout::types::void_ prev;
|
||||||
|
};
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator_impl<
|
||||||
|
Tuple,
|
||||||
|
Index,
|
||||||
|
typename std::enable_if<
|
||||||
|
sprout::types::tuple_size<Tuple>::value != 0
|
||||||
|
&& Index == sprout::types::tuple_size<Tuple>::value
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef sprout::types::void_ type;
|
||||||
|
typedef sprout::types::void_ next;
|
||||||
|
typedef sprout::types::index_iterator<Tuple, sprout::types::tuple_size<Tuple>::value - 1> prev;
|
||||||
|
};
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator_impl<
|
||||||
|
Tuple,
|
||||||
|
Index,
|
||||||
|
typename std::enable_if<
|
||||||
|
sprout::types::tuple_size<Tuple>::value != 0
|
||||||
|
&& (Index > 0)
|
||||||
|
&& (Index < sprout::types::tuple_size<Tuple>::value)
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
|
||||||
|
typedef sprout::types::index_iterator<Tuple, Index + 1> next;
|
||||||
|
typedef sprout::types::index_iterator<Tuple, Index - 1> prev;
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
//
|
||||||
|
// index_iterator
|
||||||
|
//
|
||||||
|
template<typename Tuple, std::ptrdiff_t Index>
|
||||||
|
struct index_iterator
|
||||||
|
: public sprout::types::detail::index_iterator_impl<Tuple, Index>
|
||||||
|
, public std::integral_constant<std::ptrdiff_t, Index>
|
||||||
|
{};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ITERATOR_INDEX_ITERATOR_HPP
|
19
sprout/type/iterator/next.hpp
Normal file
19
sprout/type/iterator/next.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef SPROUT_TYPE_ITERATOR_NEXT_HPP
|
||||||
|
#define SPROUT_TYPE_ITERATOR_NEXT_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// next
|
||||||
|
//
|
||||||
|
template<typename Iterator>
|
||||||
|
struct next {
|
||||||
|
public:
|
||||||
|
typedef typename Iterator::next type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ITERATOR_NEXT_HPP
|
19
sprout/type/iterator/prev.hpp
Normal file
19
sprout/type/iterator/prev.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef SPROUT_TYPE_ITERATOR_PREV_HPP
|
||||||
|
#define SPROUT_TYPE_ITERATOR_PREV_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// prev
|
||||||
|
//
|
||||||
|
template<typename Iterator>
|
||||||
|
struct prev {
|
||||||
|
public:
|
||||||
|
typedef typename Iterator::prev type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_ITERATOR_PREV_HPP
|
10
sprout/type/operation.hpp
Normal file
10
sprout/type/operation.hpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef SPROUT_TYPE_OPERATION_HPP
|
||||||
|
#define SPROUT_TYPE_OPERATION_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/operation/append_back.hpp>
|
||||||
|
#include <sprout/type/operation/append_front.hpp>
|
||||||
|
#include <sprout/type/operation/push_back.hpp>
|
||||||
|
#include <sprout/type/operation/push_front.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_OPERATION_HPP
|
38
sprout/type/operation/append_back.hpp
Normal file
38
sprout/type/operation/append_back.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef SPROUT_TYPE_OPERATION_APPEND_BACK_HPP
|
||||||
|
#define SPROUT_TYPE_OPERATION_APPEND_BACK_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// append_back
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename InputTuple>
|
||||||
|
struct append_back {
|
||||||
|
private:
|
||||||
|
template<typename IndexTuple1, typename IndexTuple2>
|
||||||
|
struct apply_impl;
|
||||||
|
template<std::ptrdiff_t... Indexes1, std::ptrdiff_t... Indexes2>
|
||||||
|
struct apply_impl<sprout::index_tuple<Indexes1...>, sprout::index_tuple<Indexes2...> >
|
||||||
|
: public sprout::types::rebind_types<
|
||||||
|
Tuple
|
||||||
|
>::template apply<
|
||||||
|
typename sprout::types::tuple_element<Indexes1, Tuple>::type...,
|
||||||
|
typename sprout::types::tuple_element<Indexes2, InputTuple>::type...
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
public:
|
||||||
|
typedef typename apply_impl<
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<Tuple>::value>::type,
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<InputTuple>::value>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_OPERATION_APPEND_BACK_HPP
|
38
sprout/type/operation/append_front.hpp
Normal file
38
sprout/type/operation/append_front.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef SPROUT_TYPE_OPERATION_APPEND_FRONT_HPP
|
||||||
|
#define SPROUT_TYPE_OPERATION_APPEND_FRONT_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// append_front
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename InputTuple>
|
||||||
|
struct append_front {
|
||||||
|
private:
|
||||||
|
template<typename IndexTuple1, typename IndexTuple2>
|
||||||
|
struct apply_impl;
|
||||||
|
template<std::ptrdiff_t... Indexes1, std::ptrdiff_t... Indexes2>
|
||||||
|
struct apply_impl<sprout::index_tuple<Indexes1...>, sprout::index_tuple<Indexes2...> >
|
||||||
|
: public sprout::types::rebind_types<
|
||||||
|
Tuple
|
||||||
|
>::template apply<
|
||||||
|
typename sprout::types::tuple_element<Indexes2, InputTuple>::type...,
|
||||||
|
typename sprout::types::tuple_element<Indexes1, Tuple>::type...
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
public:
|
||||||
|
typedef typename apply_impl<
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<Tuple>::value>::type,
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<InputTuple>::value>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_OPERATION_APPEND_FRONT_HPP
|
37
sprout/type/operation/push_back.hpp
Normal file
37
sprout/type/operation/push_back.hpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef SPROUT_TYPE_OPERATION_PUSH_BACK_HPP
|
||||||
|
#define SPROUT_TYPE_OPERATION_PUSH_BACK_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// push_back
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename T>
|
||||||
|
struct push_back {
|
||||||
|
private:
|
||||||
|
template<typename IndexTuple>
|
||||||
|
struct apply_impl;
|
||||||
|
template<std::ptrdiff_t... Indexes>
|
||||||
|
struct apply_impl<sprout::index_tuple<Indexes...> >
|
||||||
|
: public sprout::types::rebind_types<
|
||||||
|
Tuple
|
||||||
|
>::template apply<
|
||||||
|
typename sprout::types::tuple_element<Indexes, Tuple>::type...,
|
||||||
|
T
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
public:
|
||||||
|
typedef typename apply_impl<
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<Tuple>::value>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_OPERATION_PUSH_BACK_HPP
|
37
sprout/type/operation/push_front.hpp
Normal file
37
sprout/type/operation/push_front.hpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef SPROUT_TYPE_OPERATION_PUSH_FRONT_HPP
|
||||||
|
#define SPROUT_TYPE_OPERATION_PUSH_FRONT_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// push_front
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename T>
|
||||||
|
struct push_front {
|
||||||
|
private:
|
||||||
|
template<typename IndexTuple>
|
||||||
|
struct apply_impl;
|
||||||
|
template<std::ptrdiff_t... Indexes>
|
||||||
|
struct apply_impl<sprout::index_tuple<Indexes...> >
|
||||||
|
: public sprout::types::rebind_types<
|
||||||
|
Tuple
|
||||||
|
>::template apply<
|
||||||
|
T,
|
||||||
|
typename sprout::types::tuple_element<Indexes, Tuple>::type...
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
public:
|
||||||
|
typedef typename apply_impl<
|
||||||
|
typename sprout::index_range<0, sprout::types::tuple_size<Tuple>::value>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_OPERATION_PUSH_FRONT_HPP
|
29
sprout/type/rebind_types.hpp
Normal file
29
sprout/type/rebind_types.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef SPROUT_TYPE_REBIND_TYPES_HPP
|
||||||
|
#define SPROUT_TYPE_REBIND_TYPES_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/type_tuple.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// rebind_types
|
||||||
|
//
|
||||||
|
template<typename Tuple>
|
||||||
|
struct rebind_types;
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
struct rebind_types<sprout::types::type_tuple<Ts...> > {
|
||||||
|
public:
|
||||||
|
template<typename... Types>
|
||||||
|
struct apply {
|
||||||
|
public:
|
||||||
|
typedef sprout::types::type_tuple<Types...> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace types
|
||||||
|
|
||||||
|
using sprout::types::rebind_types;
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_REBIND_TYPES_HPP
|
7
sprout/type/seq/algorithm.hpp
Normal file
7
sprout/type/seq/algorithm.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef SPROUT_TYPE_SEQ_ALGORITHM_HPP
|
||||||
|
#define SPROUT_TYPE_SEQ_ALGORITHM_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/seq/algorithm/find.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_SEQ_ALGORITHM_HPP
|
71
sprout/type/seq/algorithm/find.hpp
Normal file
71
sprout/type/seq/algorithm/find.hpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef SPROUT_TYPE_SEQ_ALGORITHM_FIND_HPP
|
||||||
|
#define SPROUT_TYPE_SEQ_ALGORITHM_FIND_HPP
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
namespace seq {
|
||||||
|
namespace detail {
|
||||||
|
template<typename First, typename Last, typename T, typename = void>
|
||||||
|
struct find_impl;
|
||||||
|
template<typename First, typename Last, typename T>
|
||||||
|
struct find_impl<
|
||||||
|
First,
|
||||||
|
Last,
|
||||||
|
T,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<First, Last>::value
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef Last type;
|
||||||
|
};
|
||||||
|
template<typename First, typename Last, typename T>
|
||||||
|
struct find_impl<
|
||||||
|
First,
|
||||||
|
Last,
|
||||||
|
T,
|
||||||
|
typename std::enable_if<
|
||||||
|
!std::is_same<First, Last>::value
|
||||||
|
&& std::is_same<typename sprout::types::deref<First>::type, T>::value
|
||||||
|
>::type
|
||||||
|
> {
|
||||||
|
public:
|
||||||
|
typedef First type;
|
||||||
|
};
|
||||||
|
template<typename First, typename Last, typename T>
|
||||||
|
struct find_impl<
|
||||||
|
First,
|
||||||
|
Last,
|
||||||
|
T,
|
||||||
|
typename std::enable_if<
|
||||||
|
!std::is_same<First, Last>::value
|
||||||
|
&& !std::is_same<typename sprout::types::deref<First>::type, T>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
: public sprout::types::seq::detail::find_impl<
|
||||||
|
typename sprout::types::next<First>::type,
|
||||||
|
Last,
|
||||||
|
T
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
//
|
||||||
|
// find
|
||||||
|
//
|
||||||
|
template<typename ForwardSequence, typename T>
|
||||||
|
struct find
|
||||||
|
: public sprout::types::seq::detail::find_impl<
|
||||||
|
typename sprout::types::begin<ForwardSequence>::type,
|
||||||
|
typename sprout::types::end<ForwardSequence>::type,
|
||||||
|
T
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
} // namespace seq
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_SEQ_ALGORITHM_FIND_HPP
|
42
sprout/type/tuple.hpp
Normal file
42
sprout/type/tuple.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef SPROUT_TYPE_TUPLE_HPP
|
||||||
|
#define SPROUT_TYPE_TUPLE_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <tuple>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// begin
|
||||||
|
//
|
||||||
|
template<typename T>
|
||||||
|
struct begin {
|
||||||
|
typedef typename T::begin type;
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// end
|
||||||
|
//
|
||||||
|
template<typename T>
|
||||||
|
struct end {
|
||||||
|
typedef typename T::end type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// tuple_size
|
||||||
|
//
|
||||||
|
template<typename T>
|
||||||
|
struct tuple_size
|
||||||
|
: public std::tuple_size<T>
|
||||||
|
{};
|
||||||
|
//
|
||||||
|
// tuple_element
|
||||||
|
//
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct tuple_element
|
||||||
|
: public std::tuple_element<I, T>
|
||||||
|
{};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_TUPLE_HPP
|
60
sprout/type/type_tuple.hpp
Normal file
60
sprout/type/type_tuple.hpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef SPROUT_TYPE_TYPE_TUPLE_HPP
|
||||||
|
#define SPROUT_TYPE_TYPE_TUPLE_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type/tuple.hpp>
|
||||||
|
#include <sprout/type/iterator.hpp>
|
||||||
|
#include <sprout/type/iterator/index_iterator.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// type_tuple
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
struct type_tuple {
|
||||||
|
public:
|
||||||
|
typedef sprout::types::index_iterator<type_tuple, 0> begin;
|
||||||
|
typedef sprout::types::index_iterator<type_tuple, sizeof...(Types)> end;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct tuple_element_impl;
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct tuple_element_impl<0, sprout::types::type_tuple<Head, Tail...> > {
|
||||||
|
public:
|
||||||
|
typedef Head type;
|
||||||
|
};
|
||||||
|
template<std::size_t I, typename Head, typename... Tail>
|
||||||
|
struct tuple_element_impl<I, sprout::types::type_tuple<Head, Tail...> >
|
||||||
|
: public sprout::types::detail::tuple_element_impl<I - 1, sprout::types::type_tuple<Tail...> >
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace types
|
||||||
|
|
||||||
|
using sprout::types::type_tuple;
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
//
|
||||||
|
// tuple_size
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
struct tuple_size<sprout::types::type_tuple<Types...> >
|
||||||
|
: public std::integral_constant<std::size_t, sizeof...(Types)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//
|
||||||
|
// tuple_element
|
||||||
|
//
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_element<I, sprout::types::type_tuple<Types...> >
|
||||||
|
: public sprout::types::detail::tuple_element_impl<I, sprout::types::type_tuple<Types...> >
|
||||||
|
{};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_TYPE_TUPLE_HPP
|
15
sprout/type/void.hpp
Normal file
15
sprout/type/void.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef SPROUT_TYPE_VOID_HPP
|
||||||
|
#define SPROUT_TYPE_VOID_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// void_
|
||||||
|
//
|
||||||
|
struct void_ {};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_VOID_HPP
|
8
sprout/variant.hpp
Normal file
8
sprout/variant.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef SPROUT_VARIANT_HPP
|
||||||
|
#define SPROUT_VARIANT_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/variant/variant.hpp>
|
||||||
|
#include <sprout/variant/get.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_VARIANT_HPP
|
21
sprout/variant/get.hpp
Normal file
21
sprout/variant/get.hpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef SPROUT_VARIANT_GET_HPP
|
||||||
|
#define SPROUT_VARIANT_GET_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/variant/variant.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
//
|
||||||
|
// get
|
||||||
|
//
|
||||||
|
template<typename U, typename... Types>
|
||||||
|
SPROUT_CONSTEXPR U const& get(sprout::variant<Types...> const& operand) {
|
||||||
|
return operand.template get<U>();
|
||||||
|
}
|
||||||
|
template<typename U, typename... Types>
|
||||||
|
U& get(sprout::variant<Types...>& operand) {
|
||||||
|
return operand.template get<U>();
|
||||||
|
}
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_VARIANT_GET_HPP
|
233
sprout/variant/variant.hpp
Normal file
233
sprout/variant/variant.hpp
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
#ifndef SPROUT_VARIANT_VARIANT_HPP
|
||||||
|
#define SPROUT_VARIANT_VARIANT_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
|
#include <sprout/utility/operation.hpp>
|
||||||
|
#include <sprout/tuple/tuple.hpp>
|
||||||
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/algorithm/find_index.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace detail {
|
||||||
|
template<typename... Types>
|
||||||
|
class variant_impl {
|
||||||
|
protected:
|
||||||
|
typedef sprout::tuples::tuple<Types...> tuple_type;;
|
||||||
|
private:
|
||||||
|
template<typename T, std::ptrdiff_t... Indexes>
|
||||||
|
static SPROUT_CONSTEXPR tuple_type init(T&& operand, sprout::index_tuple<Indexes...>) {
|
||||||
|
return sprout::tuples::make_clone<tuple_type>(
|
||||||
|
typename sprout::tuples::tuple_element<Indexes, tuple_type>::type()...,
|
||||||
|
sprout::forward<T>(operand)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
tuple_type tuple_;
|
||||||
|
int which_;
|
||||||
|
protected:
|
||||||
|
SPROUT_CONSTEXPR variant_impl()
|
||||||
|
: tuple_()
|
||||||
|
, which_()
|
||||||
|
{}
|
||||||
|
template<typename T, typename Index>
|
||||||
|
SPROUT_CONSTEXPR variant_impl(T&& operand, Index)
|
||||||
|
: tuple_(init(sprout::forward<T>(operand), typename sprout::index_range<0, Index::value>::type()))
|
||||||
|
, which_(Index::value)
|
||||||
|
{
|
||||||
|
static_assert(Index::value < sizeof...(Types), "variant<>: invalid operand");
|
||||||
|
}
|
||||||
|
void swap(variant_impl& other) SPROUT_NOEXCEPT_EXPR(
|
||||||
|
SPROUT_NOEXCEPT_EXPR(swap(std::declval<tuple_type&>(), std::declval<tuple_type&>()))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(tuple_, other.tuple_);
|
||||||
|
swap(which_, other.which_);
|
||||||
|
}
|
||||||
|
variant_impl& operator=(variant_impl const&) = default;
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
//
|
||||||
|
// variant
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
class variant
|
||||||
|
: private sprout::detail::variant_impl<Types...>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef sprout::detail::variant_impl<Types...> impl_type;;
|
||||||
|
public:
|
||||||
|
typedef typename impl_type::tuple_type tuple_type;;
|
||||||
|
private:
|
||||||
|
template<int I>
|
||||||
|
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
I == sizeof...(Types),
|
||||||
|
bool
|
||||||
|
>::type eq(tuple_type const& l, tuple_type const& r, int which) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<int I>
|
||||||
|
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
I != sizeof...(Types),
|
||||||
|
bool
|
||||||
|
>::type eq(tuple_type const& l, tuple_type const& r, int which) {
|
||||||
|
return I == which
|
||||||
|
? sprout::tuples::get<I>(l) == sprout::tuples::get<I>(r)
|
||||||
|
: eq<I + 1>(l, r, which)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<int I>
|
||||||
|
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
static_cast<std::size_t>(I) == sizeof...(Types),
|
||||||
|
bool
|
||||||
|
>::type lt(tuple_type const& l, tuple_type const& r, int which) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<int I>
|
||||||
|
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
static_cast<std::size_t>(I) != sizeof...(Types),
|
||||||
|
bool
|
||||||
|
>::type lt(tuple_type const& l, tuple_type const& r, int which) {
|
||||||
|
return I == which
|
||||||
|
? sprout::tuples::get<I>(l) < sprout::tuples::get<I>(r)
|
||||||
|
: lt<I + 1>(l, r, which)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<int I, typename Elem, typename Traits>
|
||||||
|
static typename std::enable_if<
|
||||||
|
static_cast<std::size_t>(I) == sizeof...(Types),
|
||||||
|
std::basic_ostream<Elem, Traits>&
|
||||||
|
>::type output(std::basic_ostream<Elem, Traits>& os, tuple_type const& t, int which) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<int I, typename Elem, typename Traits>
|
||||||
|
static typename std::enable_if<
|
||||||
|
static_cast<std::size_t>(I) != sizeof...(Types),
|
||||||
|
std::basic_ostream<Elem, Traits>&
|
||||||
|
>::type output(std::basic_ostream<Elem, Traits>& os, tuple_type const& t, int which) {
|
||||||
|
return I == which
|
||||||
|
? os << sprout::tuples::get<I>(t)
|
||||||
|
: output<I + 1>(os, t, which)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
using impl_type::tuple_;
|
||||||
|
using impl_type::which_;
|
||||||
|
public:
|
||||||
|
// construct/copy/destruct
|
||||||
|
SPROUT_CONSTEXPR variant()
|
||||||
|
: impl_type()
|
||||||
|
{}
|
||||||
|
variant(variant const&) = default;
|
||||||
|
template<typename T>
|
||||||
|
SPROUT_CONSTEXPR variant(T&& operand)
|
||||||
|
: impl_type(sprout::forward<T>(operand), sprout::types::find_index<tuple_type, T>())
|
||||||
|
{}
|
||||||
|
// modifiers
|
||||||
|
void swap(variant& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(impl_type::swap(other))) {
|
||||||
|
impl_type::swap(other);
|
||||||
|
}
|
||||||
|
variant& operator=(variant const& rhs) {
|
||||||
|
static_cast<impl_type&>(*this) = rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
variant& operator=(variant&& rhs) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable<impl_type>::value) {
|
||||||
|
static_cast<impl_type&>(*this) = sprout::move(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
variant& operator=(T&& rhs) {
|
||||||
|
static_cast<impl_type&>(*this) = variant(sprout::forward<T>(rhs));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// queries
|
||||||
|
SPROUT_CONSTEXPR int which() const {
|
||||||
|
return which_;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR bool empty() const {
|
||||||
|
return sizeof...(Types) == 0;
|
||||||
|
}
|
||||||
|
// relational
|
||||||
|
friend SPROUT_CONSTEXPR bool operator==(variant const& lhs, variant const& rhs) {
|
||||||
|
return lhs.which_ == rhs.which_ && eq<0>(lhs.tuple_, rhs.tuple_, lhs.which_);
|
||||||
|
}
|
||||||
|
friend SPROUT_CONSTEXPR bool operator!=(variant const& lhs, variant const& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
friend SPROUT_CONSTEXPR bool operator<(variant const& lhs, variant const& rhs) {
|
||||||
|
return lhs.which_ < rhs.which_
|
||||||
|
|| (lhs.which_ == rhs.which_ && lt<0>(lhs.tuple_, rhs.tuple_, lhs.which_))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
friend SPROUT_CONSTEXPR bool operator>(variant const& lhs, variant const& rhs) {
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
friend SPROUT_CONSTEXPR bool operator<=(variant const& lhs, variant const& rhs) {
|
||||||
|
return !(rhs < lhs);
|
||||||
|
}
|
||||||
|
friend SPROUT_CONSTEXPR bool operator>=(variant const& lhs, variant const& rhs) {
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Elem, typename Traits>
|
||||||
|
friend std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& lhs, variant const& rhs) {
|
||||||
|
return output<0>(lhs, rhs.tuple_, rhs.which_);
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
|
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
||||||
|
U const&
|
||||||
|
>::type get() const {
|
||||||
|
return sprout::types::find_index<tuple_type, U>::value == static_cast<std::size_t>(which_)
|
||||||
|
? sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_)
|
||||||
|
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
typename std::enable_if<
|
||||||
|
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
||||||
|
U&
|
||||||
|
>::type get() {
|
||||||
|
return sprout::types::find_index<tuple_type, U>::value == which_
|
||||||
|
? sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_)
|
||||||
|
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// swap
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
inline void swap(
|
||||||
|
sprout::variant<Types...>& lhs,
|
||||||
|
sprout::variant<Types...>& rhs
|
||||||
|
) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
//
|
||||||
|
// tuple_size
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
struct tuple_size<sprout::variant<Types...> >
|
||||||
|
: public std::tuple_size<typename sprout::variant<Types...>::tuple_tyep>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//
|
||||||
|
// tuple_element
|
||||||
|
//
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_element<I, sprout::variant<Types...> >
|
||||||
|
: public std::tuple_element<I, typename sprout::variant<Types...>::tuple_tyep>
|
||||||
|
{};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_VARIANT_VARIANT_HPP
|
Loading…
Reference in a new issue