remove Pair, more standard tuple usage etc

master
Daniel Kolesa 2017-01-28 18:52:34 +01:00
parent 7e96183648
commit 2e7bba2c95
13 changed files with 71 additions and 318 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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
);
}

View File

@ -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))
)

View File

@ -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) {

View File

@ -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 */

View File

@ -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>;

View File

@ -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>

View File

@ -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("{");

View File

@ -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))...),

View File

@ -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)>(),