Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iostream>
- namespace au
- {
- template<class ... Types>
- struct tuple;
- template<class ... Types>
- struct tuple_sizeof;
- template<class T, class ... Types>
- struct tuple_sizeof<T, Types...>
- {
- static const size_t value = tuple_sizeof<Types...>::value + 1;
- };
- template<>
- struct tuple_sizeof<>
- {
- static const size_t value = 0;
- };
- template<class T>
- struct tuple_size;
- template<class ... Types>
- struct tuple_size<tuple<Types...>>
- {
- static const size_t value = tuple_sizeof<Types...>::value;
- };
- template<size_t I, class ... Types>
- struct get_type;
- template<size_t I, class T, class ... Types>
- struct get_type<I, T, Types...>
- {
- typedef typename get_type<I-1, Types...>::type type;
- };
- template<class T, class ... Types>
- struct get_type<0, T, Types...>
- {
- typedef T type;
- };
- template<size_t I, class T>
- struct tuple_element;
- template<size_t I, class ... Types>
- struct tuple_element<I, tuple<Types...>>
- {
- typedef typename get_type<I, Types...>::type type;
- };
- template <>
- struct tuple<> { };
- template<class T, class ... Types>
- struct tuple<T, Types...>
- {
- tuple() = default;
- tuple(T&& arg, Types&& ... args)
- : head(std::forward<T>(arg))
- , tail(std::forward<Types>(args)...){}
- tuple(tuple<T, Types...> const &other)
- : head(other.head)
- , tail(other.tail){}
- tuple(tuple<T, Types...> &&other)
- : head(std::move(other.head))
- , tail(std::move(other.tail)){}
- tuple<T, Types...>& operator=(const tuple<T, Types...>& other)
- {
- head = other.head;
- tail = other.tail;
- return *this;
- }
- tuple<T, Types...>& operator=(tuple<T, Types...>&& other)
- {
- head = std::move(other.head);
- tail = std::move(other.tail);
- return *this;
- }
- T head;
- tuple<Types...> tail;
- };
- template<size_t I, class ... UTypes>
- struct get_value;
- template<size_t I, class U, class ... UTypes>
- struct get_value<I, U, UTypes...>
- {
- static typename tuple_element<I, tuple<U, UTypes...> >::type const& value(tuple<U, UTypes...>const & t)
- {
- return get_value<I-1, UTypes...>::value(t.tail);
- }
- static typename tuple_element<I, tuple<U, UTypes...> >::type& value(tuple<U, UTypes...>& t)
- {
- return get_value<I-1, UTypes...>::value(t.tail);
- }
- };
- template<class U, class ... UTypes>
- struct get_value<0, U, UTypes...>
- {
- static typename tuple_element<0, tuple<U, UTypes...> >::type const& value(tuple<U, UTypes...>const & t)
- {
- return t.head;
- }
- static typename tuple_element<0, tuple<U, UTypes...> >::type& value(tuple<U, UTypes...>& t)
- {
- return t.head;
- }
- };
- template<class U, class ... UTypes>
- struct find;
- template<class T, class U, class ... UTypes>
- struct find<T, U, UTypes...>
- {
- static constexpr T& value(tuple<U, UTypes...>& t)
- {
- return t.tail;
- }
- static constexpr T const& value(tuple<U, UTypes...>const & t)
- {
- return t.tail;
- }
- };
- template<class T, class ... UTypes>
- struct find<T, T, UTypes...>
- {
- static constexpr T& value(tuple<T, UTypes...>& t)
- {
- return t.head;
- }
- static constexpr T const& value(tuple<T, UTypes...>const & t)
- {
- return t.head;
- }
- };
- template <class... Types>
- tuple<Types...> make_tuple(Types... args)
- {
- return tuple<Types...>(std::forward<Types>(args)...);
- }
- template<size_t I, class... Types>
- typename tuple_element<I, tuple<Types...> >::type const& get(tuple<Types...> const & t)
- {
- return get_value<I, Types...>::value(t);
- };
- template<size_t I, class... Types>
- typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...> & t)
- {
- return get_value<I, Types...>::value(t);
- };
- template< class T, class... Types >
- constexpr T& get(tuple<Types...>& t) noexcept
- {
- return find<T, Types...>::value(t);
- }
- template< class T, class... Types >
- constexpr T const& get(tuple<Types...> const& t) noexcept
- {
- return find<T, Types...>::value(t);
- }
- } //au
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement