remove Pair, more standard tuple usage etc
parent
7e96183648
commit
2e7bba2c95
|
@ -1,9 +1,10 @@
|
|||
#include <tuple>
|
||||
|
||||
#include <ostd/algorithm.hh>
|
||||
#include <ostd/vector.hh>
|
||||
#include <ostd/map.hh>
|
||||
#include <ostd/range.hh>
|
||||
#include <ostd/io.hh>
|
||||
#include <ostd/tuple.hh>
|
||||
|
||||
using namespace ostd;
|
||||
|
||||
|
@ -64,10 +65,10 @@ int main() {
|
|||
writefln("{ %-#(%s: %d, %) }", m);
|
||||
|
||||
/* tuple format test */
|
||||
Tuple<int, float, char const *> xt[] = {
|
||||
make_tuple(5, 3.14f, "foo"),
|
||||
make_tuple(3, 1.23f, "bar"),
|
||||
make_tuple(9, 8.66f, "baz")
|
||||
std::tuple<int, float, char const *> xt[] = {
|
||||
std::make_tuple(5, 3.14f, "foo"),
|
||||
std::make_tuple(3, 1.23f, "bar"),
|
||||
std::make_tuple(9, 8.66f, "baz")
|
||||
};
|
||||
writefln("[ %#(<%d|%f|%s>%|, %) ]", xt);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ int main() {
|
|||
writeln(v);
|
||||
}
|
||||
|
||||
/* 2-tuple zip uses Pair */
|
||||
/* 2-tuple zip uses std::pair */
|
||||
writeln("2-tuple range zip");
|
||||
for (auto v: iter({ 5, 10, 15, 20 }).zip(iter({ 6, 11, 16, 21 }))) {
|
||||
writeln(v.first, ", ", v.second);
|
||||
|
|
|
@ -58,7 +58,7 @@ int main() {
|
|||
writeln(v);
|
||||
}
|
||||
|
||||
/* 2-tuple zip uses Pair */
|
||||
/* 2-tuple zip uses std::pair */
|
||||
writeln("2-tuple range zip");
|
||||
for (auto v: iter({ 5, 10, 15, 20 }) | zip(iter({ 6, 11, 16, 21 }))) {
|
||||
writeln(v.first, ", ", v.second);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ostd/functional.hh"
|
||||
#include "ostd/range.hh"
|
||||
#include "ostd/utility.hh"
|
||||
|
@ -683,13 +685,13 @@ inline void generate(R range, F gen) {
|
|||
}
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline Pair<R1, R2> swap_ranges(R1 range1, R2 range2) {
|
||||
inline std::pair<R1, R2> swap_ranges(R1 range1, R2 range2) {
|
||||
while (!range1.empty() && !range2.empty()) {
|
||||
detail::swap_adl(range1.front(), range2.front());
|
||||
range1.pop_front();
|
||||
range2.pop_front();
|
||||
}
|
||||
return ostd::make_pair(range1, range2);
|
||||
return std::make_pair(range1, range2);
|
||||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
|
|
|
@ -517,7 +517,7 @@ namespace detail {
|
|||
T const &item, A const &...args
|
||||
) {
|
||||
return FmtTupleUnpacker<I - 1>::unpack(
|
||||
writer, fmtn, esc, fmt, item, get<I - 1>(item), args...
|
||||
writer, fmtn, esc, fmt, item, std::get<I - 1>(item), args...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -547,7 +547,7 @@ namespace detail {
|
|||
T const &item, EnableIf<IsTupleLike<T>, bool> = true
|
||||
) {
|
||||
if (expandval) {
|
||||
return FmtTupleUnpacker<TupleSize<T>>::unpack(
|
||||
return FmtTupleUnpacker<std::tuple_size<T>::value>::unpack(
|
||||
writer, fmtn, esc, fmt, item
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
#define OSTD_FUNCTIONAL_HH
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <new>
|
||||
#include <functional>
|
||||
|
||||
#include "ostd/platform.hh"
|
||||
#include "ostd/memory.hh"
|
||||
|
@ -438,47 +440,6 @@ typename ToHash<T>::Result to_hash(T const &v) {
|
|||
return ToHash<T>()(v);
|
||||
}
|
||||
|
||||
/* reference wrapper */
|
||||
|
||||
template<typename T>
|
||||
struct ReferenceWrapper {
|
||||
using Type = T;
|
||||
|
||||
ReferenceWrapper(T &v): p_ptr(address_of(v)) {}
|
||||
ReferenceWrapper(ReferenceWrapper const &) = default;
|
||||
ReferenceWrapper(T &&) = delete;
|
||||
|
||||
ReferenceWrapper &operator=(ReferenceWrapper const &) = default;
|
||||
|
||||
operator T &() const { return *p_ptr; }
|
||||
T &get() const { return *p_ptr; }
|
||||
|
||||
private:
|
||||
T *p_ptr;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
ReferenceWrapper<T> ref(T &v) {
|
||||
return ReferenceWrapper<T>(v);
|
||||
}
|
||||
template<typename T>
|
||||
ReferenceWrapper<T> ref(ReferenceWrapper<T> v) {
|
||||
return ReferenceWrapper<T>(v);
|
||||
}
|
||||
template<typename T>
|
||||
void ref(T const &&) = delete;
|
||||
|
||||
template<typename T>
|
||||
ReferenceWrapper<T const> cref(T const &v) {
|
||||
return ReferenceWrapper<T>(v);
|
||||
}
|
||||
template<typename T>
|
||||
ReferenceWrapper<T const> cref(ReferenceWrapper<T> v) {
|
||||
return ReferenceWrapper<T>(v);
|
||||
}
|
||||
template<typename T>
|
||||
void cref(T const &&) = delete;
|
||||
|
||||
/* mem_fn */
|
||||
|
||||
namespace detail {
|
||||
|
@ -613,7 +574,7 @@ namespace detail {
|
|||
public:
|
||||
explicit FuncCore(F &&f):
|
||||
f_stor(
|
||||
piecewise_construct,
|
||||
std::piecewise_construct,
|
||||
forward_as_tuple(std::move(f)),
|
||||
forward_as_tuple()
|
||||
)
|
||||
|
@ -621,7 +582,7 @@ public:
|
|||
|
||||
explicit FuncCore(F const &f, A const &a):
|
||||
f_stor(
|
||||
piecewise_construct,
|
||||
std::piecewise_construct,
|
||||
forward_as_tuple(f),
|
||||
forward_as_tuple(a)
|
||||
)
|
||||
|
@ -629,7 +590,7 @@ public:
|
|||
|
||||
explicit FuncCore(F const &f, A &&a):
|
||||
f_stor(
|
||||
piecewise_construct,
|
||||
std::piecewise_construct,
|
||||
forward_as_tuple(f),
|
||||
forward_as_tuple(std::move(a))
|
||||
)
|
||||
|
@ -637,7 +598,7 @@ public:
|
|||
|
||||
explicit FuncCore(F &&f, A &&a):
|
||||
f_stor(
|
||||
piecewise_construct,
|
||||
std::piecewise_construct,
|
||||
forward_as_tuple(std::move(f)),
|
||||
forward_as_tuple(std::move(a))
|
||||
)
|
||||
|
|
|
@ -563,7 +563,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename ...Args>
|
||||
Pair<Range, bool> emplace(Args &&...args) {
|
||||
std::pair<Range, bool> emplace(Args &&...args) {
|
||||
rehash_ahead(1);
|
||||
E elem(std::forward<Args>(args)...);
|
||||
if (Multihash) {
|
||||
|
@ -574,7 +574,7 @@ public:
|
|||
Size h = bucket(B::get_key(elem));
|
||||
Chain *ch = insert(h);
|
||||
B::swap_elem(ch->value, elem);
|
||||
return make_pair(Range(ch), true);
|
||||
return std::make_pair(Range(ch), true);
|
||||
}
|
||||
Size h = bucket(B::get_key(elem));
|
||||
Chain *found = nullptr;
|
||||
|
@ -591,7 +591,7 @@ public:
|
|||
found = insert(h);
|
||||
B::swap_elem(found->value, elem);
|
||||
}
|
||||
return make_pair(Range(found), ins);
|
||||
return std::make_pair(Range(found), ins);
|
||||
}
|
||||
|
||||
Size erase(const K &key) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define OSTD_INTERNAL_TUPLE_HH
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "ostd/types.hh"
|
||||
#include "ostd/type_traits.hh"
|
||||
|
@ -16,10 +17,6 @@ namespace ostd {
|
|||
|
||||
template<typename ...A>
|
||||
class Tuple;
|
||||
template<typename T, typename U>
|
||||
struct Pair;
|
||||
template<typename T, Size I>
|
||||
struct Array;
|
||||
|
||||
/* tuple size */
|
||||
|
||||
|
@ -118,36 +115,19 @@ inline const TupleElement<I, Tuple<A...>> &&get(const Tuple<A...> &&) noexcept;
|
|||
/* pair specializations */
|
||||
|
||||
template<typename T, typename U>
|
||||
constexpr bool IsTupleLike<Pair<T, U>> = true;
|
||||
constexpr bool IsTupleLike<std::pair<T, U>> = true;
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> &get(Pair<T, U> &) noexcept;
|
||||
inline TupleElement<I, std::pair<T, U>> &get(std::pair<T, U> &) noexcept;
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline const TupleElement<I, Pair<T, U>> &get(const Pair<T, U> &) noexcept;
|
||||
inline const TupleElement<I, std::pair<T, U>> &get(const std::pair<T, U> &) noexcept;
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&) noexcept;
|
||||
inline TupleElement<I, std::pair<T, U>> &&get(std::pair<T, U> &&) noexcept;
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline const TupleElement<I, Pair<T, U>> &&get(const Pair<T, U> &&) noexcept;
|
||||
|
||||
/* array specializations */
|
||||
|
||||
template<typename T, Size I>
|
||||
constexpr bool IsTupleLike<Array<T, I>> = true;
|
||||
|
||||
template<Size I, typename T, Size S>
|
||||
inline T &get(Array<T, S> &) noexcept;
|
||||
|
||||
template<Size I, typename T, Size S>
|
||||
inline const T &get(const Array<T, S> &) noexcept;
|
||||
|
||||
template<Size I, typename T, Size S>
|
||||
inline T &&get(Array<T, S> &&) noexcept;
|
||||
|
||||
template<Size I, typename T, Size S>
|
||||
inline const T &&get(const Array<T, S> &&) noexcept;
|
||||
inline const TupleElement<I, std::pair<T, U>> &&get(const std::pair<T, U> &&) noexcept;
|
||||
|
||||
/* make tuple indices */
|
||||
|
||||
|
|
22
ostd/map.hh
22
ostd/map.hh
|
@ -6,6 +6,8 @@
|
|||
#ifndef OSTD_MAP_HH
|
||||
#define OSTD_MAP_HH
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ostd/types.hh"
|
||||
#include "ostd/utility.hh"
|
||||
#include "ostd/memory.hh"
|
||||
|
@ -18,7 +20,7 @@ namespace ostd {
|
|||
|
||||
namespace detail {
|
||||
template<typename K, typename T, typename A> struct MapBase {
|
||||
using Element = Pair<K const, T>;
|
||||
using Element = std::pair<K const, T>;
|
||||
|
||||
static inline K const &get_key(Element &e) {
|
||||
return e.first;
|
||||
|
@ -42,11 +44,11 @@ namespace detail {
|
|||
typename C, typename A, bool IsMultihash
|
||||
>
|
||||
struct MapImpl: detail::Hashtable<detail::MapBase<K, T, A>,
|
||||
Pair<K const, T>, K, T, H, C, A, IsMultihash
|
||||
std::pair<K const, T>, K, T, H, C, A, IsMultihash
|
||||
> {
|
||||
private:
|
||||
using Base = detail::Hashtable<detail::MapBase<K, T, A>,
|
||||
Pair<K const, T>, K, T, H, C, A, IsMultihash
|
||||
std::pair<K const, T>, K, T, H, C, A, IsMultihash
|
||||
>;
|
||||
|
||||
public:
|
||||
|
@ -56,14 +58,14 @@ namespace detail {
|
|||
using Difference = Ptrdiff;
|
||||
using Hasher = H;
|
||||
using KeyEqual = C;
|
||||
using Value = Pair<K const, T>;
|
||||
using Value = std::pair<K const, T>;
|
||||
using Reference = Value &;
|
||||
using Pointer = AllocatorPointer<A>;
|
||||
using ConstPointer = AllocatorConstPointer<A>;
|
||||
using Range = HashRange<Pair<K const, T>>;
|
||||
using ConstRange = HashRange<Pair<K const, T> const>;
|
||||
using LocalRange = BucketRange<Pair<K const, T>>;
|
||||
using ConstLocalRange = BucketRange<Pair<K const, T> const>;
|
||||
using Range = HashRange<std::pair<K const, T>>;
|
||||
using ConstRange = HashRange<std::pair<K const, T> const>;
|
||||
using LocalRange = BucketRange<std::pair<K const, T>>;
|
||||
using ConstLocalRange = BucketRange<std::pair<K const, T> const>;
|
||||
using Allocator = A;
|
||||
|
||||
explicit MapImpl(
|
||||
|
@ -185,7 +187,7 @@ template<
|
|||
typename K, typename T,
|
||||
typename H = ToHash<K>,
|
||||
typename C = EqualWithCstr<K>,
|
||||
typename A = Allocator<Pair<K const, T>>
|
||||
typename A = Allocator<std::pair<K const, T>>
|
||||
>
|
||||
using Map = detail::MapImpl<K, T, H, C, A, false>;
|
||||
|
||||
|
@ -193,7 +195,7 @@ template<
|
|||
typename K, typename T,
|
||||
typename H = ToHash<K>,
|
||||
typename C = EqualWithCstr<K>,
|
||||
typename A = Allocator<Pair<K const, T>>
|
||||
typename A = Allocator<std::pair<K const, T>>
|
||||
>
|
||||
using Multimap = detail::MapImpl<K, T, H, C, A, true>;
|
||||
|
||||
|
|
|
@ -1588,7 +1588,7 @@ namespace detail {
|
|||
|
||||
template<typename T, typename U>
|
||||
struct ZipValueType<T, U> {
|
||||
using Type = Pair<T, U>;
|
||||
using Type = std::pair<T, U>;
|
||||
};
|
||||
|
||||
template<typename ...T>
|
||||
|
|
|
@ -964,8 +964,8 @@ struct ToString<ConstCharRange> {
|
|||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct ToString<Pair<T, U>> {
|
||||
using Argument = Pair<T, U>;
|
||||
struct ToString<std::pair<T, U>> {
|
||||
using Argument = std::pair<T, U>;
|
||||
using Result = String;
|
||||
String operator()(Argument const &v) {
|
||||
String ret("{");
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace detail {
|
|||
IsLvalueReference<H> && (
|
||||
IsLvalueReference<T> || IsSame<
|
||||
RemoveReference<T>,
|
||||
ReferenceWrapper<RemoveReference<H>>
|
||||
std::reference_wrapper<RemoveReference<H>>
|
||||
>
|
||||
)
|
||||
) || (IsRvalueReference<H> && !IsLvalueReference<T>),
|
||||
|
@ -87,7 +87,7 @@ namespace detail {
|
|||
IsLvalueReference<H> && (
|
||||
IsLvalueReference<T> || IsSame<
|
||||
RemoveReference<T>,
|
||||
ReferenceWrapper<RemoveReference<H>>
|
||||
std::reference_wrapper<RemoveReference<H>>
|
||||
>
|
||||
)
|
||||
),
|
||||
|
@ -104,7 +104,7 @@ namespace detail {
|
|||
IsLvalueReference<H> && (
|
||||
IsLvalueReference<T> || IsSame<
|
||||
RemoveReference<T>,
|
||||
ReferenceWrapper<RemoveReference<H>>
|
||||
std::reference_wrapper<RemoveReference<H>>
|
||||
>
|
||||
)
|
||||
),
|
||||
|
@ -121,7 +121,7 @@ namespace detail {
|
|||
IsLvalueReference<H> && (
|
||||
IsLvalueReference<T> || IsSame<
|
||||
RemoveReference<T>,
|
||||
ReferenceWrapper<RemoveReference<H>>
|
||||
std::reference_wrapper<RemoveReference<H>>
|
||||
>
|
||||
)
|
||||
),
|
||||
|
@ -536,7 +536,7 @@ namespace detail {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct MakeTupleReturnType<ReferenceWrapper<T>> {
|
||||
struct MakeTupleReturnType<std::reference_wrapper<T>> {
|
||||
using Type = T &;
|
||||
};
|
||||
|
||||
|
@ -636,23 +636,11 @@ constexpr bool UsesAllocator<Tuple<T...>, A> = true;
|
|||
|
||||
/* piecewise pair stuff */
|
||||
|
||||
template<typename T, typename U>
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
Pair<T, U>::Pair(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
):
|
||||
first(
|
||||
std::forward<A1>(get<I1>(fa))...),
|
||||
second(std::forward<A2>(get<I2>(sa))...
|
||||
)
|
||||
{}
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename U>
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase<T, U, 0>::CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
):
|
||||
p_first(std::forward<A1>(get<I1>(fa))...),
|
||||
|
@ -662,7 +650,7 @@ namespace detail {
|
|||
template<typename T, typename U>
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase<T, U, 1>::CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
):
|
||||
T(std::forward<A1>(get<I1>(fa))...),
|
||||
|
@ -672,7 +660,7 @@ namespace detail {
|
|||
template<typename T, typename U>
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase<T, U, 2>::CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
):
|
||||
U(std::forward<A2>(get<I2>(sa))...),
|
||||
|
@ -682,7 +670,7 @@ namespace detail {
|
|||
template<typename T, typename U>
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase<T, U, 3>::CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
):
|
||||
T(std::forward<A1>(get<I1>(fa))...),
|
||||
|
|
217
ostd/utility.hh
217
ostd/utility.hh
|
@ -74,218 +74,37 @@ namespace detail {
|
|||
|
||||
/* pair */
|
||||
|
||||
struct PiecewiseConstruct {};
|
||||
constexpr PiecewiseConstruct piecewise_construct = {};
|
||||
template<typename T, typename U>
|
||||
constexpr Size TupleSize<std::pair<T, U>> = 2;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct Pair {
|
||||
T first;
|
||||
U second;
|
||||
|
||||
Pair() = default;
|
||||
~Pair() = default;
|
||||
|
||||
Pair(Pair const &) = default;
|
||||
Pair(Pair &&) = default;
|
||||
|
||||
Pair(T const &x, U const &y): first(x), second(y) {}
|
||||
|
||||
template<typename TT, typename UU>
|
||||
Pair(TT &&x, UU &&y):
|
||||
first(std::forward<TT>(x)), second(std::forward<UU>(y))
|
||||
{}
|
||||
|
||||
template<typename TT, typename UU>
|
||||
Pair(Pair<TT, UU> const &v): first(v.first), second(v.second) {}
|
||||
|
||||
template<typename TT, typename UU>
|
||||
Pair(Pair<TT, UU> &&v):
|
||||
first(std::move(v.first)), second(std::move(v.second))
|
||||
{}
|
||||
|
||||
template<typename ...A1, typename ...A2>
|
||||
Pair(PiecewiseConstruct pc, Tuple<A1...> fa, Tuple<A2...> sa):
|
||||
Pair(
|
||||
pc, fa, sa,
|
||||
detail::MakeTupleIndices<sizeof...(A1)>(),
|
||||
detail::MakeTupleIndices<sizeof...(A2)>()
|
||||
)
|
||||
{}
|
||||
|
||||
Pair &operator=(Pair const &v) {
|
||||
first = v.first;
|
||||
second = v.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename TT, typename UU>
|
||||
Pair &operator=(Pair<TT, UU> const &v) {
|
||||
first = v.first;
|
||||
second = v.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Pair &operator=(Pair &&v) noexcept(
|
||||
IsNothrowMoveAssignable<T> && IsNothrowMoveAssignable<U>
|
||||
) {
|
||||
first = std::move(v.first);
|
||||
second = std::move(v.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename TT, typename UU>
|
||||
Pair &operator=(Pair<TT, UU> &&v) {
|
||||
first = std::forward<TT>(v.first);
|
||||
second = std::forward<UU>(v.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(Pair &v) noexcept(
|
||||
noexcept(detail::swap_adl(first, v.first)) &&
|
||||
noexcept(detail::swap_adl(second, v.second))
|
||||
) {
|
||||
detail::swap_adl(first, v.first);
|
||||
detail::swap_adl(second, v.second);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
Pair(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ReferenceWrapper;
|
||||
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct MakePairRetBase {
|
||||
using Type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct MakePairRetBase<ReferenceWrapper<T>> {
|
||||
using Type = T &;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct MakePairRet {
|
||||
using Type = typename detail::MakePairRetBase<Decay<T>>::Type;
|
||||
};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T, typename U>
|
||||
inline Pair<
|
||||
typename detail::MakePairRet<T>::Type, typename detail::MakePairRet<U>::Type
|
||||
> make_pair(T &&a, U &&b) {
|
||||
return Pair<
|
||||
typename detail::MakePairRet<T>::Type,
|
||||
typename detail::MakePairRet<U>::Type
|
||||
>(std::forward<T>(a), std::forward<U>(b));
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator==(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return (x.first == y.first) && (x.second == y.second);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator!=(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return (x.first != y.first) || (x.second != y.second);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator<(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return (x.first < y.first)
|
||||
? true
|
||||
: ((y.first < x.first)
|
||||
? false
|
||||
: ((x.second < y.second)
|
||||
? true
|
||||
: false));
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator>(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return (y < x);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator<=(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline constexpr bool operator>=(Pair<T, U> const &x, Pair<T, U> const &y) {
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
constexpr Size TupleSize<Pair<T, U>> = 2;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct TupleElementBase<0, Pair<T, U>> {
|
||||
struct TupleElementBase<0, std::pair<T, U>> {
|
||||
using Type = T;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct TupleElementBase<1, Pair<T, U>> {
|
||||
struct TupleElementBase<1, std::pair<T, U>> {
|
||||
using Type = U;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<Size>
|
||||
struct GetPair;
|
||||
|
||||
template<>
|
||||
struct GetPair<0> {
|
||||
template<typename T, typename U>
|
||||
static T &get(Pair<T, U> &p) { return p.first; }
|
||||
template<typename T, typename U>
|
||||
static T const &get(Pair<T, U> const &p) { return p.first; }
|
||||
template<typename T, typename U>
|
||||
static T &&get(Pair<T, U> &&p) { return std::forward<T>(p.first); }
|
||||
template<typename T, typename U>
|
||||
static T const &&get(Pair<T, U> const &&p) {
|
||||
return std::forward<T const>(p.first);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct GetPair<1> {
|
||||
template<typename T, typename U>
|
||||
static U &get(Pair<T, U> &p) { return p.second; }
|
||||
template<typename T, typename U>
|
||||
static U const &get(Pair<T, U> const &p) { return p.second; }
|
||||
template<typename T, typename U>
|
||||
static U &&get(Pair<T, U> &&p) { return std::forward<U>(p.second); }
|
||||
template<typename T, typename U>
|
||||
static T const &&get(Pair<T, U> const &&p) {
|
||||
return std::forward<T const>(p.second);
|
||||
}
|
||||
};
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, std::pair<T, U>> &get(std::pair<T, U> &p) noexcept {
|
||||
return std::get<I>(p);
|
||||
}
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> &get(Pair<T, U> &p) noexcept {
|
||||
return detail::GetPair<I>::get(p);
|
||||
inline TupleElement<I, std::pair<T, U>> const &get(std::pair<T, U> const &p) noexcept {
|
||||
return std::get<I>(p);
|
||||
}
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> const &get(Pair<T, U> const &p) noexcept {
|
||||
return detail::GetPair<I>::get(p);
|
||||
inline TupleElement<I, std::pair<T, U>> &&get(std::pair<T, U> &&p) noexcept {
|
||||
return std::get<I>(std::move(p));
|
||||
}
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&p) noexcept {
|
||||
return detail::GetPair<I>::get(std::move(p));
|
||||
}
|
||||
|
||||
template<Size I, typename T, typename U>
|
||||
inline TupleElement<I, Pair<T, U>> const &&get(Pair<T, U> const &&p) noexcept {
|
||||
return detail::GetPair<I>::get(std::move(p));
|
||||
inline TupleElement<I, std::pair<T, U>> const &&get(std::pair<T, U> const &&p) noexcept {
|
||||
return std::get<I>(std::move(p));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
@ -330,7 +149,7 @@ namespace detail {
|
|||
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
);
|
||||
|
||||
|
@ -357,7 +176,7 @@ namespace detail {
|
|||
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
);
|
||||
|
||||
|
@ -383,7 +202,7 @@ namespace detail {
|
|||
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
);
|
||||
|
||||
|
@ -407,7 +226,7 @@ namespace detail {
|
|||
|
||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||
CompressedPairBase(
|
||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
std::piecewise_construct_t, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||
);
|
||||
|
||||
|
@ -430,7 +249,7 @@ namespace detail {
|
|||
{}
|
||||
|
||||
template<typename ...A1, typename ...A2>
|
||||
CompressedPair(PiecewiseConstruct pc, Tuple<A1...> fa, Tuple<A2...> sa):
|
||||
CompressedPair(std::piecewise_construct_t pc, Tuple<A1...> fa, Tuple<A2...> sa):
|
||||
Base(
|
||||
pc, fa, sa,
|
||||
detail::MakeTupleIndices<sizeof...(A1)>(),
|
||||
|
|
Loading…
Reference in New Issue