2015-04-15 21:38:15 +00:00
|
|
|
/* Utilities for OctaSTD.
|
|
|
|
*
|
|
|
|
* This file is part of OctaSTD. See COPYING.md for futher information.
|
|
|
|
*/
|
|
|
|
|
2015-07-13 19:08:55 +00:00
|
|
|
#ifndef OSTD_UTILITY_HH
|
|
|
|
#define OSTD_UTILITY_HH
|
2015-04-15 21:38:15 +00:00
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
2017-01-25 00:44:22 +00:00
|
|
|
#include <utility>
|
2017-01-28 18:39:50 +00:00
|
|
|
#include <tuple>
|
2017-01-25 00:44:22 +00:00
|
|
|
|
2015-07-13 19:08:55 +00:00
|
|
|
#include "ostd/type_traits.hh"
|
2015-04-18 15:46:44 +00:00
|
|
|
|
2015-07-13 19:07:14 +00:00
|
|
|
namespace ostd {
|
2015-04-28 23:01:22 +00:00
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
namespace detail {
|
|
|
|
template<typename T, typename U,
|
2016-01-12 22:24:40 +00:00
|
|
|
bool = IsSame<RemoveCv<T>, RemoveCv<U>>,
|
2016-01-12 21:45:26 +00:00
|
|
|
bool = IsEmpty<T>, bool = IsEmpty<U>
|
2016-07-31 19:40:25 +00:00
|
|
|
>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch = detail::Undefined<T>();
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
/* neither empty */
|
|
|
|
template<typename T, typename U, bool Same>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch<T, U, Same, false, false> = 0;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
/* first empty */
|
|
|
|
template<typename T, typename U, bool Same>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch<T, U, Same, true, false> = 1;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
/* second empty */
|
|
|
|
template<typename T, typename U, bool Same>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch<T, U, Same, false, true> = 2;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
/* both empty, not the same */
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch<T, U, false, true, true> = 3;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
/* both empty and same */
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
constexpr size_t CompressedPairSwitch<T, U, true, true, true> = 1;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename T, typename U, size_t = CompressedPairSwitch<T, U>>
|
2015-06-13 15:32:03 +00:00
|
|
|
struct CompressedPairBase;
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
struct CompressedPairBase<T, U, 0> {
|
|
|
|
T p_first;
|
|
|
|
U p_second;
|
|
|
|
|
2015-06-13 15:36:47 +00:00
|
|
|
template<typename TT, typename UU>
|
2016-07-31 19:40:25 +00:00
|
|
|
CompressedPairBase(TT &&a, UU &&b):
|
2017-01-25 00:44:22 +00:00
|
|
|
p_first(std::forward<TT>(a)), p_second(std::forward<UU>(b))
|
2016-07-31 19:40:25 +00:00
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2016-09-11 12:08:56 +00:00
|
|
|
CompressedPairBase(
|
2017-01-28 18:06:52 +00:00
|
|
|
std::piecewise_construct_t,
|
|
|
|
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
2016-09-11 12:08:56 +00:00
|
|
|
);
|
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
T &first() { return p_first; }
|
2016-06-23 18:18:35 +00:00
|
|
|
T const &first() const { return p_first; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
U &second() { return p_second; }
|
2016-06-23 18:18:35 +00:00
|
|
|
U const &second() const { return p_second; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
void swap(CompressedPairBase &v) {
|
2015-07-11 17:50:13 +00:00
|
|
|
swap_adl(p_first, v.p_first);
|
|
|
|
swap_adl(p_second, v.p_second);
|
2015-06-13 15:32:03 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
struct CompressedPairBase<T, U, 1>: T {
|
|
|
|
U p_second;
|
|
|
|
|
2015-06-13 15:36:47 +00:00
|
|
|
template<typename TT, typename UU>
|
2016-07-31 19:40:25 +00:00
|
|
|
CompressedPairBase(TT &&a, UU &&b):
|
2017-01-25 00:44:22 +00:00
|
|
|
T(std::forward<TT>(a)), p_second(std::forward<UU>(b))
|
2016-07-31 19:40:25 +00:00
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2016-09-11 12:08:56 +00:00
|
|
|
CompressedPairBase(
|
2017-01-28 18:06:52 +00:00
|
|
|
std::piecewise_construct_t,
|
|
|
|
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
2016-09-11 12:08:56 +00:00
|
|
|
);
|
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
T &first() { return *this; }
|
2016-06-23 18:18:35 +00:00
|
|
|
T const &first() const { return *this; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
U &second() { return p_second; }
|
2016-06-23 18:18:35 +00:00
|
|
|
U const &second() const { return p_second; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
void swap(CompressedPairBase &v) {
|
2015-07-11 17:50:13 +00:00
|
|
|
swap_adl(p_second, v.p_second);
|
2015-06-13 15:32:03 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
struct CompressedPairBase<T, U, 2>: U {
|
|
|
|
T p_first;
|
|
|
|
|
2015-06-13 15:36:47 +00:00
|
|
|
template<typename TT, typename UU>
|
2016-07-31 19:40:25 +00:00
|
|
|
CompressedPairBase(TT &&a, UU &&b):
|
2017-01-25 00:44:22 +00:00
|
|
|
U(std::forward<UU>(b)), p_first(std::forward<TT>(a))
|
2016-07-31 19:40:25 +00:00
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2016-09-11 12:08:56 +00:00
|
|
|
CompressedPairBase(
|
2017-01-28 18:06:52 +00:00
|
|
|
std::piecewise_construct_t,
|
|
|
|
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
2016-09-11 12:08:56 +00:00
|
|
|
);
|
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
T &first() { return p_first; }
|
2016-06-23 18:18:35 +00:00
|
|
|
T const &first() const { return p_first; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
U &second() { return *this; }
|
2016-06-23 18:18:35 +00:00
|
|
|
U const &second() const { return *this; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
void swap(CompressedPairBase &v) {
|
2015-07-11 17:50:13 +00:00
|
|
|
swap_adl(p_first, v.p_first);
|
2015-06-13 15:32:03 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
struct CompressedPairBase<T, U, 3>: T, U {
|
2015-06-13 15:36:47 +00:00
|
|
|
template<typename TT, typename UU>
|
2016-07-31 19:40:25 +00:00
|
|
|
CompressedPairBase(TT &&a, UU &&b):
|
2017-01-25 00:44:22 +00:00
|
|
|
T(std::forward<TT>(a)), U(std::forward<UU>(b))
|
2016-07-31 19:40:25 +00:00
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2016-09-11 12:08:56 +00:00
|
|
|
CompressedPairBase(
|
2017-01-28 18:06:52 +00:00
|
|
|
std::piecewise_construct_t,
|
|
|
|
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
2016-09-11 12:08:56 +00:00
|
|
|
);
|
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
T &first() { return *this; }
|
2016-06-23 18:18:35 +00:00
|
|
|
T const &first() const { return *this; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
U &second() { return *this; }
|
2016-06-23 18:18:35 +00:00
|
|
|
U const &second() const { return *this; }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
void swap(CompressedPairBase &) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
struct CompressedPair: CompressedPairBase<T, U> {
|
2015-06-14 01:36:20 +00:00
|
|
|
using Base = CompressedPairBase<T, U>;
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2015-06-13 15:36:47 +00:00
|
|
|
template<typename TT, typename UU>
|
2016-07-31 19:40:25 +00:00
|
|
|
CompressedPair(TT &&a, UU &&b):
|
2017-01-25 00:44:22 +00:00
|
|
|
Base(std::forward<TT>(a), std::forward<UU>(b))
|
2016-07-31 19:40:25 +00:00
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
|
2016-09-11 12:08:56 +00:00
|
|
|
template<typename ...A1, typename ...A2>
|
2017-01-28 18:06:52 +00:00
|
|
|
CompressedPair(
|
|
|
|
std::piecewise_construct_t pc,
|
|
|
|
std::tuple<A1...> fa, std::tuple<A2...> sa
|
|
|
|
):
|
2016-09-11 12:08:56 +00:00
|
|
|
Base(
|
|
|
|
pc, fa, sa,
|
2017-01-28 18:06:52 +00:00
|
|
|
std::make_index_sequence<sizeof...(A1)>(),
|
|
|
|
std::make_index_sequence<sizeof...(A2)>()
|
2016-09-11 12:08:56 +00:00
|
|
|
)
|
|
|
|
{}
|
|
|
|
|
2015-06-13 15:32:03 +00:00
|
|
|
T &first() { return Base::first(); }
|
2016-06-23 18:18:35 +00:00
|
|
|
T const &first() const { return Base::first(); }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
U &second() { return Base::second(); }
|
2016-06-23 18:18:35 +00:00
|
|
|
U const &second() const { return Base::second(); }
|
2015-06-13 15:32:03 +00:00
|
|
|
|
|
|
|
void swap(CompressedPair &v) {
|
|
|
|
Base::swap(v);
|
|
|
|
}
|
|
|
|
};
|
2017-01-28 18:06:52 +00:00
|
|
|
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2017-01-28 18:06:52 +00:00
|
|
|
CompressedPairBase<T, U, 0>::CompressedPairBase(
|
|
|
|
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
|
|
|
):
|
|
|
|
p_first(std::forward<A1>(std::get<I1>(fa))...),
|
|
|
|
p_second(std::forward<A2>(std::get<I2>(sa))...)
|
|
|
|
{}
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2017-01-28 18:06:52 +00:00
|
|
|
CompressedPairBase<T, U, 1>::CompressedPairBase(
|
|
|
|
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
|
|
|
):
|
|
|
|
T(std::forward<A1>(std::get<I1>(fa))...),
|
|
|
|
p_second(std::forward<A2>(std::get<I2>(sa))...)
|
|
|
|
{}
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2017-01-28 18:06:52 +00:00
|
|
|
CompressedPairBase<T, U, 2>::CompressedPairBase(
|
|
|
|
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
|
|
|
):
|
|
|
|
U(std::forward<A2>(std::get<I2>(sa))...),
|
|
|
|
p_first(std::forward<A1>(std::get<I1>(fa))...)
|
|
|
|
{}
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
2017-01-30 18:11:39 +00:00
|
|
|
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
|
2017-01-28 18:06:52 +00:00
|
|
|
CompressedPairBase<T, U, 3>::CompressedPairBase(
|
|
|
|
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
|
|
|
|
std::index_sequence<I1...>, std::index_sequence<I2...>
|
|
|
|
):
|
|
|
|
T(std::forward<A1>(std::get<I1>(fa))...),
|
|
|
|
U(std::forward<A2>(std::get<I2>(sa))...)
|
|
|
|
{}
|
2015-06-13 15:32:03 +00:00
|
|
|
} /* namespace detail */
|
|
|
|
|
2015-07-13 19:07:14 +00:00
|
|
|
} /* namespace ostd */
|
2015-06-03 22:01:23 +00:00
|
|
|
|
2016-02-07 21:17:15 +00:00
|
|
|
#endif
|