ditch the separate "type" struct

master
Daniel Kolesa 2015-04-27 19:38:34 +01:00
parent 990a7646da
commit d7778cf259
7 changed files with 142 additions and 174 deletions

View File

@ -53,7 +53,7 @@ namespace octa {
template<typename R>
void insertion_sort(R range) {
insertion_sort(range, Less<typename RangeTraits<R>::value>());
insertion_sort(range, Less<typename RangeTraits<R>::value_type>());
}
/* sort (introsort) */
@ -130,7 +130,7 @@ namespace octa {
template<typename R>
void sort(R range) {
sort(range, Less<typename RangeTraits<R>::value>());
sort(range, Less<typename RangeTraits<R>::value_type>());
}
/* min/max(_element) */

View File

@ -13,17 +13,15 @@
namespace octa {
template<typename T, size_t N>
struct Array {
struct type {
typedef T value;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
typedef size_t size;
typedef ptrdiff_t difference;
typedef PointerRange< T> range;
typedef PointerRange<const T> const_range;
};
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
typedef PointerRange< T> range;
typedef PointerRange<const T> const_range;
T &operator[](size_t i) { return p_buf[i]; }
const T &operator[](size_t i) const { return p_buf[i]; }
@ -47,10 +45,10 @@ namespace octa {
swap(p_buf, v.p_buf);
}
typename type::range each() {
range each() {
return PointerRange<T>(p_buf, p_buf + N);
}
typename type::const_range each() const {
const_range each() const {
return PointerRange<const T>(p_buf, p_buf + N);
}

View File

@ -17,11 +17,9 @@ namespace octa {
#define __OCTA_DEFINE_BINARY_OP(name, op, rettype) \
template<typename T> struct name { \
bool operator()(const T &x, const T &y) const { return x op y; } \
struct type { \
typedef T first; \
typedef T second; \
typedef rettype result; \
}; \
typedef T first_argument_type; \
typedef T second_argument_type; \
typedef rettype result_type; \
};
__OCTA_DEFINE_BINARY_OP(Less, <, bool)
@ -45,29 +43,24 @@ namespace octa {
template<typename T> struct LogicalNot {
bool operator()(const T &x) const { return !x; }
struct type {
typedef T argument;
typedef bool result;
};
typedef T argument_type;
typedef bool result_type;
};
template<typename T> struct Negate {
bool operator()(const T &x) const { return -x; }
struct type {
typedef T argument;
typedef T result;
};
typedef T argument_type;
typedef T result_type;
};
template<typename T> struct BinaryNegate {
struct type {
typedef typename T::type::first first;
typedef typename T::type::second second;
typedef bool result;
};
typedef typename T::first_argument_type first_argument_type;
typedef typename T::second_argument_type second_argument_type;
typedef bool result_type;
explicit BinaryNegate(const T &f): p_fn(f) {}
bool operator()(const typename type::first &x,
const typename type::second &y) {
bool operator()(const first_argument_type &x,
const second_argument_type &y) {
return !p_fn(x, y);
}
private:
@ -75,12 +68,11 @@ namespace octa {
};
template<typename T> struct UnaryNegate {
struct type {
typedef typename T::type::argument argument;
typedef bool result;
};
typedef typename T::argument_type argument_type;
typedef bool result_type;
explicit UnaryNegate(const T &f): p_fn(f) {}
bool operator()(const typename type::argument &x) {
bool operator()(const argument_type &x) {
return !p_fn(x);
}
private:
@ -135,33 +127,31 @@ namespace octa {
template<typename, typename> struct __OctaMemTypes;
template<typename T, typename R, typename ...A>
struct __OctaMemTypes<T, R(A...)> {
typedef R result;
typedef T argument;
typedef R result_type;
typedef T argument_type;
};
template<typename T, typename R, typename A>
struct __OctaMemTypes<T, R(A)> {
typedef R result;
typedef T first;
typedef A second;
typedef R result_type;
typedef T first_argument_type;
typedef A second_argument_type;
};
template<typename T, typename R, typename ...A>
struct __OctaMemTypes<T, R(A...) const> {
typedef R result;
typedef const T argument;
typedef R result_type;
typedef const T argument_type;
};
template<typename T, typename R, typename A>
struct __OctaMemTypes<T, R(A) const> {
typedef R result;
typedef const T first;
typedef A second;
typedef R result_type;
typedef const T first_argument_type;
typedef A second_argument_type;
};
template<typename R, typename T>
class __OctaMemFn {
class __OctaMemFn: __OctaMemTypes<T, R> {
R T::*p_ptr;
public:
struct type: __OctaMemTypes<T, R> {};
__OctaMemFn(R T::*ptr): p_ptr(ptr) {}
template<typename... A>
auto operator()(T &obj, A &&...args) ->
@ -326,26 +316,20 @@ namespace octa {
template<typename R, typename...>
struct __OctaFunction {
struct type {
typedef R result;
};
typedef R result_type;
};
template<typename R, typename T>
struct __OctaFunction<R, T> {
struct type {
typedef R result;
typedef T argument;
};
typedef R result_type;
typedef T argument_type;
};
template<typename R, typename T, typename U>
struct __OctaFunction<R, T, U> {
struct type {
typedef R result;
typedef T first;
typedef U second;
};
typedef R result_type;
typedef T first_argument_type;
typedef U second_argument_type;
};
template<typename R, typename ...A>

View File

@ -19,15 +19,13 @@ namespace std {
initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {}
public:
struct type {
typedef T value;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
typedef size_t size;
typedef ptrdiff_t difference;
};
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
initializer_list(): p_buf(nullptr), p_len(0) {}

View File

@ -24,7 +24,7 @@ namespace octa {
template<typename U>
static int __octa_test(...);
template<typename U>
static char __octa_test(typename U::type::element * = 0);
static char __octa_test(typename U::element_type * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1);
};
@ -33,12 +33,12 @@ namespace octa {
struct __OctaPtrTraitsElementType;
template<typename T> struct __OctaPtrTraitsElementType<T, true> {
typedef typename T::type::element type;
typedef typename T::element_type type;
};
template<template<typename, typename...> class T, typename U, typename ...A>
struct __OctaPtrTraitsElementType<T<U, A...>, true> {
typedef typename T<U, A...>::type::element type;
typedef typename T<U, A...>::element_type type;
};
template<template<typename, typename...> class T, typename U, typename ...A>
@ -51,7 +51,7 @@ namespace octa {
template<typename U>
static int __octa_test(...);
template<typename U>
static char __octa_test(typename U::type::difference * = 0);
static char __octa_test(typename U::difference_type * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1);
};
@ -62,7 +62,7 @@ namespace octa {
};
template<typename T> struct __OctaPtrTraitsDifferenceType<T, true> {
typedef typename T::type::difference type;
typedef typename T::difference_type type;
};
template<typename T, typename U>
@ -70,7 +70,7 @@ namespace octa {
template<typename V>
static int __octa_test(...);
template<typename V>
static char __octa_test(typename V::type::template rebind<U> * = 0);
static char __octa_test(typename V::template rebind<U> * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1);
};
@ -84,7 +84,7 @@ namespace octa {
typename ...A, typename V
>
struct __OctaPtrTraitsRebind<T<U, A...>, V, true> {
typedef typename T<U, A...>::type::template rebind<V> type;
typedef typename T<U, A...>::template rebind<V> type;
};
template<template<typename, typename...> class T, typename U,
@ -98,8 +98,8 @@ namespace octa {
struct PointerTraits {
typedef T pointer;
typedef typename __OctaPtrTraitsElementType <T>::type element;
typedef typename __OctaPtrTraitsDifferenceType<T>::type difference;
typedef typename __OctaPtrTraitsElementType <T>::type element_type;
typedef typename __OctaPtrTraitsDifferenceType<T>::type difference_type;
template<typename U>
using rebind = typename __OctaPtrTraitsRebind<T, U>::type;
@ -108,8 +108,8 @@ namespace octa {
struct __OctaNAT {};
public:
static T pointer_to(Conditional<IsVoid<element>::value,
__OctaNAT, element
static T pointer_to(Conditional<IsVoid<element_type>::value,
__OctaNAT, element_type
> &r) {
return T::pointer_to(r);
}
@ -118,9 +118,9 @@ namespace octa {
template<typename T>
struct PointerTraits<T *> {
typedef T *pointer;
typedef T element;
typedef T element_type;
typedef ptrdiff_t difference;
typedef ptrdiff_t difference_type;
template<typename U> using rebind = U *;
@ -128,8 +128,8 @@ namespace octa {
struct __OctaNAT {};
public:
static T pointer_to(Conditional<IsVoid<element>::value,
__OctaNAT, element
static T pointer_to(Conditional<IsVoid<element_type>::value,
__OctaNAT, element_type
> &r) {
return octa::address_of(r);
}
@ -165,7 +165,7 @@ namespace octa {
template<typename T>
static int __octa_ptr_test(...);
template<typename T>
static char __octa_ptr_test(typename T::type::pointer * = 0);
static char __octa_ptr_test(typename T::pointer * = 0);
template<typename T> struct __OctaHasPtr: IntegralConstant<bool,
(sizeof(__octa_ptr_test<T>(0)) == 1)
@ -173,7 +173,7 @@ namespace octa {
template<typename T, typename D, bool = __OctaHasPtr<D>::value>
struct __OctaPtrTypeBase {
typedef typename D::type::pointer type;
typedef typename D::pointer type;
};
template<typename T, typename D> struct __OctaPtrTypeBase<T, D, false> {
@ -186,11 +186,9 @@ namespace octa {
template<typename T, typename D = DefaultDelete<T>>
struct Box {
struct type {
typedef T element;
typedef D deleter;
typedef typename __OctaPtrType<T, D>::type pointer;
};
typedef T element_type;
typedef D deleter_type;
typedef typename __OctaPtrType<T, D>::type pointer;
private:
struct __OctaNAT { int x; };
@ -208,17 +206,16 @@ namespace octa {
"Box constructed with null fptr deleter");
}
explicit Box(typename type::pointer p): p_ptr(p), p_del() {
explicit Box(pointer p): p_ptr(p), p_del() {
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
Box(typename type::pointer p, Conditional<IsReference<D>::value,
Box(pointer p, Conditional<IsReference<D>::value,
D, AddLvalueReference<const D>
> d): p_ptr(p), p_del(d) {}
Box(typename type::pointer p, RemoveReference<D> &&d): p_ptr(p),
p_del(move(d)) {
Box(pointer p, RemoveReference<D> &&d): p_ptr(p), p_del(move(d)) {
static_assert(!IsReference<D>::value,
"rvalue deleter cannot be a ref");
}
@ -227,9 +224,7 @@ namespace octa {
template<typename TT, typename DD>
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value
&& IsConvertible<typename Box<TT, DD>::type::pointer,
typename type::pointer
>::value
&& IsConvertible<typename Box<TT, DD>::pointer, pointer>::value
&& IsConvertible<DD, D>::value
&& (!IsReference<D>::value || IsSame<D, DD>::value)
> = __OctaNAT()): p_ptr(u.release()),
@ -243,8 +238,7 @@ namespace octa {
template<typename TT, typename DD>
EnableIf<!IsArray<TT>::value
&& IsConvertible<typename Box<TT, DD>::type::pointer,
typename type::pointer>::value
&& IsConvertible<typename Box<TT, DD>::pointer, pointer>::value
&& IsAssignable<D &, DD &&>::value,
Box &
> operator=(Box<TT, DD> &&u) {
@ -261,23 +255,23 @@ namespace octa {
~Box() { reset(); }
AddLvalueReference<T> operator*() const { return *p_ptr; }
typename type::pointer operator->() const { return p_ptr; }
pointer operator->() const { return p_ptr; }
explicit operator bool() const { return p_ptr != nullptr; }
typename type::pointer get() const { return p_ptr; }
pointer get() const { return p_ptr; }
D_ref get_deleter() { return p_del; }
D_cref get_deleter() const { return p_del; }
typename type::pointer release() {
typename type::pointer p = p_ptr;
pointer release() {
pointer p = p_ptr;
p_ptr = nullptr;
return p;
}
void reset(typename type::pointer p = nullptr) {
typename type::pointer tmp = p_ptr;
void reset(pointer p = nullptr) {
pointer tmp = p_ptr;
p_ptr = p;
if (tmp) p_del(tmp);
}
@ -294,8 +288,8 @@ namespace octa {
};
template<typename T, typename U, bool = IsSame<
RemoveCV<typename PointerTraits<T>::element>,
RemoveCV<typename PointerTraits<U>::element>
RemoveCV<typename PointerTraits<T>::element_type>,
RemoveCV<typename PointerTraits<U>::element_type>
>::value> struct __OctaSameOrLessCVQualifiedBase: IsConvertible<T, U> {};
template<typename T, typename U>
@ -310,11 +304,9 @@ namespace octa {
template<typename T, typename D>
struct Box<T[], D> {
struct type {
typedef T element;
typedef D deleter;
typedef typename __OctaPtrType<T, D>::type pointer;
};
typedef T element_type;
typedef D deleter_type;
typedef typename __OctaPtrType<T, D>::type pointer;
private:
struct __OctaNAT { int x; };
@ -332,28 +324,24 @@ namespace octa {
"Box constructed with null fptr deleter");
}
template<typename U>
explicit Box(U p, EnableIf<__OctaSameOrLessCVQualified<U,
typename type::pointer>::value, __OctaNAT
template<typename U> explicit Box(U p, EnableIf<
__OctaSameOrLessCVQualified<U, pointer>::value, __OctaNAT
> = __OctaNAT()): p_ptr(p), p_del() {
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
template<typename U>
Box(U p, Conditional<IsReference<D>::value,
template<typename U> Box(U p, Conditional<IsReference<D>::value,
D, AddLvalueReference<const D>
> d, EnableIf<__OctaSameOrLessCVQualified<U,
typename type::pointer>::value, __OctaNAT
> d, EnableIf<__OctaSameOrLessCVQualified<U, pointer>::value, __OctaNAT
> = __OctaNAT()): p_ptr(p), p_del(d) {}
Box(nullptr_t, Conditional<IsReference<D>::value,
D, AddLvalueReference<const D>
> d): p_ptr(), p_del(d) {}
template<typename U>
Box(U p, RemoveReference<D> &&d, EnableIf<__OctaSameOrLessCVQualified<U,
typename type::pointer>::value, __OctaNAT
template<typename U> Box(U p, RemoveReference<D> &&d, EnableIf<
__OctaSameOrLessCVQualified<U, pointer>::value, __OctaNAT
> = __OctaNAT()): p_ptr(p), p_del(move(d)) {
static_assert(!IsReference<D>::value,
"rvalue deleter cannot be a ref");
@ -368,8 +356,8 @@ namespace octa {
template<typename TT, typename DD>
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value
&& __OctaSameOrLessCVQualified<typename Box<TT, DD>::type::pointer,
typename type::pointer>::value
&& __OctaSameOrLessCVQualified<typename Box<TT, DD>::pointer,
pointer>::value
&& IsConvertible<DD, D>::value
&& (!IsReference<D>::value || IsSame<D, DD>::value)> = __OctaNAT()
): p_ptr(u.release()), p_del(forward<DD>(u.get_deleter())) {}
@ -382,8 +370,8 @@ namespace octa {
template<typename TT, typename DD>
EnableIf<IsArray<TT>::value
&& __OctaSameOrLessCVQualified<typename Box<TT, DD>::type::pointer,
typename type::pointer>::value
&& __OctaSameOrLessCVQualified<typename Box<TT, DD>::pointer,
pointer>::value
&& IsAssignable<D &, DD &&>::value,
Box &
> operator=(Box<TT, DD> &&u) {
@ -405,27 +393,27 @@ namespace octa {
explicit operator bool() const { return p_ptr != nullptr; }
typename type::pointer get() const { return p_ptr; }
pointer get() const { return p_ptr; }
D_ref get_deleter() { return p_del; }
D_cref get_deleter() const { return p_del; }
typename type::pointer release() {
typename type::pointer p = p_ptr;
pointer release() {
pointer p = p_ptr;
p_ptr = nullptr;
return p;
}
template<typename U> EnableIf<
__OctaSameOrLessCVQualified<U, typename type::pointer>::value, void
__OctaSameOrLessCVQualified<U, pointer>::value, void
> reset(U p) {
typename type::pointer tmp = p_ptr;
pointer tmp = p_ptr;
p_ptr = p;
if (tmp) p_del(tmp);
}
void reset(nullptr_t) {
typename type::pointer tmp = p_ptr;
pointer tmp = p_ptr;
p_ptr = nullptr;
if (tmp) p_del(tmp);
}

View File

@ -20,9 +20,9 @@ namespace octa {
template<typename T>
struct RangeTraits {
typedef typename T::type::category category;
typedef typename T::type::value value;
typedef typename T::type::reference reference;
typedef typename T::range_category range_category;
typedef typename T::value_type value_type;
typedef typename T::reference reference;
};
template<typename T>
@ -46,11 +46,9 @@ namespace octa {
template<typename B, typename C, typename V, typename R = V &>
struct InputRangeBase {
struct type {
typedef C category;
typedef V value;
typedef R reference;
};
typedef C range_category;
typedef V value_type;
typedef R reference;
__OctaRangeIterator<B> begin() {
return __OctaRangeIterator<B>((const B &)*this);
@ -62,17 +60,15 @@ namespace octa {
template<typename V, typename R = V &>
struct OutputRangeBase {
struct type {
typedef OutputRange category;
typedef V value;
typedef R reference;
};
typedef OutputRange range_category;
typedef V value_type;
typedef R reference;
};
template<typename T>
struct ReverseRange: InputRangeBase<ReverseRange<T>,
typename RangeTraits<T>::category,
typename RangeTraits<T>::value,
typename RangeTraits<T>::range_category,
typename RangeTraits<T>::value_type,
typename RangeTraits<T>::reference
> {
ReverseRange(): p_range() {}
@ -139,9 +135,9 @@ namespace octa {
template<typename T>
struct MoveRange: InputRangeBase<MoveRange<T>,
typename RangeTraits<T>::category,
typename RangeTraits<T>::value,
typename RangeTraits<T>::value &&
typename RangeTraits<T>::range_category,
typename RangeTraits<T>::value_type,
typename RangeTraits<T>::value_type &&
> {
MoveRange(): p_range() {}
MoveRange(const T &range): p_range(range) {}
@ -178,10 +174,14 @@ namespace octa {
return p_range != v.p_range;
}
typename RangeTraits<T>::value &&first() { return move(p_range.first()); }
typename RangeTraits<T>::value &&last () { return move(p_range.last ()); }
typename RangeTraits<T>::value_type &&first() {
return move(p_range.first());
}
typename RangeTraits<T>::value_type &&last () {
return move(p_range.last());
}
typename RangeTraits<T>::value &&operator[](size_t i) {
typename RangeTraits<T>::value_type &&operator[](size_t i) {
return move(p_range[i]);
}
@ -189,7 +189,9 @@ namespace octa {
return MoveRange<T>(p_range.slice(start, end));
}
void put(const typename RangeTraits<T>::value &v) { p_range.put(v); }
void put(const typename RangeTraits<T>::value_type &v) {
p_range.put(v);
}
private:
T p_range;
@ -292,7 +294,7 @@ namespace octa {
template<typename T>
struct EnumeratedRange: InputRangeBase<EnumeratedRange<T>,
InputRange, typename RangeTraits<T>::value,
InputRange, typename RangeTraits<T>::value_type,
EnumeratedValue<typename RangeTraits<T>::reference>
> {
EnumeratedRange(): p_range(), p_index(0) {}

View File

@ -33,17 +33,15 @@ namespace octa {
public:
enum { MIN_SIZE = 8 };
struct type {
typedef T value;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
typedef size_t size;
typedef ptrdiff_t difference;
typedef PointerRange< T> range;
typedef PointerRange<const T> const_range;
};
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
typedef PointerRange< T> range;
typedef PointerRange<const T> const_range;
Vector(): p_buf(nullptr), p_len(0), p_cap(0) {}
@ -268,10 +266,10 @@ namespace octa {
return insert_range(idx, il.range());
}
typename type::range each() {
range each() {
return PointerRange<T>(p_buf, p_buf + p_len);
}
typename type::const_range each() const {
const_range each() const {
return PointerRange<const T>(p_buf, p_buf + p_len);
}