start moving over to standard tuple

This commit is contained in:
q66 2017-01-28 18:30:31 +01:00
parent 5ec32439c5
commit 7e96183648
3 changed files with 85 additions and 27 deletions

View file

@ -7,6 +7,8 @@
#ifndef OSTD_INTERNAL_TUPLE_HH #ifndef OSTD_INTERNAL_TUPLE_HH
#define OSTD_INTERNAL_TUPLE_HH #define OSTD_INTERNAL_TUPLE_HH
#include <tuple>
#include "ostd/types.hh" #include "ostd/types.hh"
#include "ostd/type_traits.hh" #include "ostd/type_traits.hh"
@ -63,6 +65,39 @@ constexpr bool IsTupleLike<volatile T> = IsTupleLike<T>;
template<typename T> template<typename T>
constexpr bool IsTupleLike<const volatile T> = IsTupleLike<T>; constexpr bool IsTupleLike<const volatile T> = IsTupleLike<T>;
/* std::tuple specializations */
template<typename ...A>
constexpr bool IsTupleLike<std::tuple<A...>> = true;
template<typename ...T>
constexpr Size TupleSize<std::tuple<T...>> = sizeof...(T);
template<Size I, typename ...T>
struct TupleElementBase<I, std::tuple<T...>> {
using Type = std::tuple_element_t<I, std::tuple<T...>>;
};
template<Size I, typename ...A>
inline TupleElement<I, std::tuple<A...>> &get(std::tuple<A...> &t) noexcept {
return std::get<I>(t);
}
template<Size I, typename ...A>
inline const TupleElement<I, std::tuple<A...>> &get(const std::tuple<A...> &t) noexcept {
return std::get<I>(t);
}
template<Size I, typename ...A>
inline TupleElement<I, std::tuple<A...>> &&get(std::tuple<A...> &&t) noexcept {
return std::get<I>(std::move(t));
}
template<Size I, typename ...A>
inline const TupleElement<I, std::tuple<A...>> &&get(const std::tuple<A...> &&t) noexcept{
return std::get<I>(std::move(t));
}
/* tuple specializations */ /* tuple specializations */
template<typename ...A> template<typename ...A>

View file

@ -8,12 +8,14 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <new> #include <new>
#include <tuple>
#include <utility>
#include "ostd/types.hh" #include "ostd/types.hh"
#include "ostd/utility.hh" #include "ostd/utility.hh"
#include "ostd/type_traits.hh" #include "ostd/type_traits.hh"
#include "ostd/tuple.hh"
namespace ostd { namespace ostd {
@ -687,16 +689,20 @@ inline auto chunks(T n) {
namespace detail { namespace detail {
template<typename T, typename ...R, Size ...I> template<typename T, typename ...R, Size ...I>
inline auto join_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) { inline auto join_proxy(
T &&obj, std::tuple<R &&...> &&tup, std::index_sequence<I...>
) {
return obj.join(std::forward<R>( return obj.join(std::forward<R>(
get<I>(std::forward<Tuple<R &&...>>(tup)) std::get<I>(std::forward<std::tuple<R &&...>>(tup))
)...); )...);
} }
template<typename T, typename ...R, Size ...I> template<typename T, typename ...R, Size ...I>
inline auto zip_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) { inline auto zip_proxy(
T &&obj, std::tuple<R &&...> &&tup, std::index_sequence<I...>
) {
return obj.zip(std::forward<R>( return obj.zip(std::forward<R>(
get<I>(std::forward<Tuple<R &&...>>(tup)) std::get<I>(std::forward<std::tuple<R &&...>>(tup))
)...); )...);
} }
} }
@ -711,12 +717,14 @@ inline auto join(R &&range) {
template<typename R1, typename ...R> template<typename R1, typename ...R>
inline auto join(R1 &&r1, R &&...rr) { inline auto join(R1 &&r1, R &&...rr) {
return [ return [
ranges = forward_as_tuple(std::forward<R1>(r1), std::forward<R>(rr)...) ranges = std::forward_as_tuple(
std::forward<R1>(r1), std::forward<R>(rr)...
)
] (auto &&obj) mutable { ] (auto &&obj) mutable {
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
return detail::join_proxy( return detail::join_proxy(
std::forward<decltype(obj)>(obj), std::forward<decltype(obj)>(obj),
std::forward<decltype(ranges)>(ranges), Index() std::forward<decltype(ranges)>(ranges),
std::make_index_sequence<sizeof...(R) + 1>()
); );
}; };
} }
@ -731,12 +739,14 @@ inline auto zip(R &&range) {
template<typename R1, typename ...R> template<typename R1, typename ...R>
inline auto zip(R1 &&r1, R &&...rr) { inline auto zip(R1 &&r1, R &&...rr) {
return [ return [
ranges = forward_as_tuple(std::forward<R1>(r1), std::forward<R>(rr)...) ranges = std::forward_as_tuple(
std::forward<R1>(r1), std::forward<R>(rr)...
)
] (auto &&obj) mutable { ] (auto &&obj) mutable {
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
return detail::zip_proxy( return detail::zip_proxy(
std::forward<decltype(obj)>(obj), std::forward<decltype(obj)>(obj),
std::forward<decltype(ranges)>(ranges), Index() std::forward<decltype(ranges)>(ranges),
std::make_index_sequence<sizeof...(R) + 1>()
); );
}; };
} }
@ -1452,7 +1462,7 @@ namespace detail {
struct JoinRangeEmpty { struct JoinRangeEmpty {
template<typename T> template<typename T>
static bool empty(T const &tup) { static bool empty(T const &tup) {
if (!ostd::get<I>(tup).empty()) { if (!std::get<I>(tup).empty()) {
return false; return false;
} }
return JoinRangeEmpty<I + 1, N>::empty(tup); return JoinRangeEmpty<I + 1, N>::empty(tup);
@ -1471,7 +1481,7 @@ namespace detail {
struct TupleRangeEqual { struct TupleRangeEqual {
template<typename T> template<typename T>
static bool equal(T const &tup1, T const &tup2) { static bool equal(T const &tup1, T const &tup2) {
if (!ostd::get<I>(tup1).equals_front(ostd::get<I>(tup2))) { if (!std::get<I>(tup1).equals_front(std::get<I>(tup2))) {
return false; return false;
} }
return TupleRangeEqual<I + 1, N>::equal(tup1, tup2); return TupleRangeEqual<I + 1, N>::equal(tup1, tup2);
@ -1490,8 +1500,8 @@ namespace detail {
struct JoinRangePop { struct JoinRangePop {
template<typename T> template<typename T>
static bool pop(T &tup) { static bool pop(T &tup) {
if (!ostd::get<I>(tup).empty()) { if (!std::get<I>(tup).empty()) {
return ostd::get<I>(tup).pop_front(); return std::get<I>(tup).pop_front();
} }
return JoinRangePop<I + 1, N>::pop(tup); return JoinRangePop<I + 1, N>::pop(tup);
} }
@ -1509,8 +1519,8 @@ namespace detail {
struct JoinRangeFront { struct JoinRangeFront {
template<typename U> template<typename U>
static T front(U const &tup) { static T front(U const &tup) {
if (!ostd::get<I>(tup).empty()) { if (!std::get<I>(tup).empty()) {
return ostd::get<I>(tup).front(); return std::get<I>(tup).front();
} }
return JoinRangeFront<I + 1, N, T>::front(tup); return JoinRangeFront<I + 1, N, T>::front(tup);
} }
@ -1520,7 +1530,7 @@ namespace detail {
struct JoinRangeFront<N, N, T> { struct JoinRangeFront<N, N, T> {
template<typename U> template<typename U>
static T front(U const &tup) { static T front(U const &tup) {
return ostd::get<0>(tup).front(); return std::get<0>(tup).front();
} }
}; };
} }
@ -1531,7 +1541,7 @@ struct JoinRange: InputRange<JoinRange<R...>,
CommonType<RangeValue<R>...>, CommonType<RangeReference<R>...>, CommonType<RangeValue<R>...>, CommonType<RangeReference<R>...>,
CommonType<RangeSize<R>...>, CommonType<RangeDifference<R>...>> { CommonType<RangeSize<R>...>, CommonType<RangeDifference<R>...>> {
private: private:
Tuple<R...> p_ranges; std::tuple<R...> p_ranges;
public: public:
JoinRange() = delete; JoinRange() = delete;
JoinRange(R const &...ranges): p_ranges(ranges...) {} JoinRange(R const &...ranges): p_ranges(ranges...) {}
@ -1573,7 +1583,7 @@ public:
namespace detail { namespace detail {
template<typename ...T> template<typename ...T>
struct ZipValueType { struct ZipValueType {
using Type = Tuple<T...>; using Type = std::tuple<T...>;
}; };
template<typename T, typename U> template<typename T, typename U>
@ -1588,7 +1598,7 @@ namespace detail {
struct ZipRangeEmpty { struct ZipRangeEmpty {
template<typename T> template<typename T>
static bool empty(T const &tup) { static bool empty(T const &tup) {
if (ostd::get<I>(tup).empty()) { if (std::get<I>(tup).empty()) {
return true; return true;
} }
return ZipRangeEmpty<I + 1, N>::empty(tup); return ZipRangeEmpty<I + 1, N>::empty(tup);
@ -1608,7 +1618,7 @@ namespace detail {
template<typename T> template<typename T>
static bool pop(T &tup) { static bool pop(T &tup) {
return ( return (
ostd::get<I>(tup).pop_front() && ZipRangePop<I + 1, N>::pop(tup) std::get<I>(tup).pop_front() && ZipRangePop<I + 1, N>::pop(tup)
); );
} }
}; };
@ -1624,14 +1634,15 @@ namespace detail {
template<typename ...T> template<typename ...T>
struct ZipRangeFront { struct ZipRangeFront {
template<typename U, Size ...I> template<typename U, Size ...I>
static ZipValue<T...> tup_get(U const &tup, detail::TupleIndices<I...>) { static ZipValue<T...> tup_get(U const &tup, std::index_sequence<I...>) {
return ZipValue<T...>(ostd::get<I>(tup).front()...); return ZipValue<T...>(std::get<I>(tup).front()...);
} }
template<typename U> template<typename U>
static ZipValue<T...> front(U const &tup) { static ZipValue<T...> front(U const &tup) {
using Index = detail::MakeTupleIndices<sizeof...(T)>; return ZipRangeFront<T...>::tup_get(
return ZipRangeFront<T...>::tup_get(tup, Index()); tup, std::make_index_sequence<sizeof...(T)>()
);
} }
}; };
} }
@ -1643,7 +1654,7 @@ struct ZipRange: InputRange<ZipRange<R...>,
detail::ZipValue<RangeReference<R>...>, detail::ZipValue<RangeReference<R>...>,
CommonType<RangeSize<R>...>, CommonType<RangeDifference<R>...>> { CommonType<RangeSize<R>...>, CommonType<RangeDifference<R>...>> {
private: private:
Tuple<R...> p_ranges; std::tuple<R...> p_ranges;
public: public:
ZipRange() = delete; ZipRange() = delete;
ZipRange(R const &...ranges): p_ranges(ranges...) {} ZipRange(R const &...ranges): p_ranges(ranges...) {}

View file

@ -1020,6 +1020,18 @@ struct ToString<Tuple<T...>> {
} }
}; };
template<typename ...T>
struct ToString<std::tuple<T...>> {
using Argument = std::tuple<T...>;
using Result = String;
String operator()(Argument const &v) {
String ret("{");
detail::TupleToString<0, sizeof...(T)>::append(ret, v);
ret += "}";
return ret;
}
};
template<typename T> template<typename T>
typename ToString<T>::Result to_string(T const &v) { typename ToString<T>::Result to_string(T const &v) {
return ToString<RemoveCv<RemoveReference<T>>>()(v); return ToString<RemoveCv<RemoveReference<T>>>()(v);