forked from OctaForge/libostd
convert range checks to template vars
This commit is contained in:
parent
9b11c1d319
commit
a6744105dc
|
@ -27,14 +27,14 @@ namespace detail {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
static inline Size estimate_hrsize(const R &range,
|
static inline Size estimate_hrsize(const R &range,
|
||||||
EnableIf<IsFiniteRandomAccessRange<R>::value, bool> = true
|
EnableIf<IsFiniteRandomAccessRange<R>, bool> = true
|
||||||
) {
|
) {
|
||||||
return range.size();
|
return range.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
static inline Size estimate_hrsize(const R &,
|
static inline Size estimate_hrsize(const R &,
|
||||||
EnableIf<!IsFiniteRandomAccessRange<R>::value, bool> = true
|
EnableIf<!IsFiniteRandomAccessRange<R>, bool> = true
|
||||||
) {
|
) {
|
||||||
/* we have no idea how big the range actually is */
|
/* we have no idea how big the range actually is */
|
||||||
return 16;
|
return 16;
|
||||||
|
|
|
@ -86,8 +86,7 @@ namespace detail {
|
||||||
KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
KeysetImpl(KeysetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value && IsConvertible<RangeReference<R>,
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
Value>::value
|
|
||||||
>> KeysetImpl(R range, Size size = 0, const H &hf = H(),
|
>> KeysetImpl(R range, Size size = 0, const H &hf = H(),
|
||||||
const C &eqf = C(), const A &alloc = A()
|
const C &eqf = C(), const A &alloc = A()
|
||||||
): Base(size ? size : detail::estimate_hrsize(range),
|
): Base(size ? size : detail::estimate_hrsize(range),
|
||||||
|
@ -127,8 +126,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> KeysetImpl &operator=(R range) {
|
>> KeysetImpl &operator=(R range) {
|
||||||
Base::assign_range(range);
|
Base::assign_range(range);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -86,8 +86,7 @@ namespace detail {
|
||||||
MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value && IsConvertible<RangeReference<R>,
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
Value>::value
|
|
||||||
>> MapImpl(R range, Size size = 0, const H &hf = H(),
|
>> MapImpl(R range, Size size = 0, const H &hf = H(),
|
||||||
const C &eqf = C(), const A &alloc = A()
|
const C &eqf = C(), const A &alloc = A()
|
||||||
): Base(size ? size : detail::estimate_hrsize(range),
|
): Base(size ? size : detail::estimate_hrsize(range),
|
||||||
|
@ -127,8 +126,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> MapImpl &operator=(R range) {
|
>> MapImpl &operator=(R range) {
|
||||||
Base::assign_range(range);
|
Base::assign_range(range);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
154
ostd/range.hh
154
ostd/range.hh
|
@ -73,113 +73,129 @@ namespace detail {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, InputRangeTag
|
RangeCategory<T>, InputRangeTag
|
||||||
>::value> struct IsInputRangeBase: False {};
|
>::value> struct IsInputRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsInputRangeBase<T, true>: True {};
|
struct IsInputRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsInputRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsInputRangeBase<T, true>: detail::IsInputRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
|
||||||
struct IsInputRange: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsInputRange<T, true>: detail::IsInputRangeBase<T>::Type {};
|
static constexpr bool IsInputRange = detail::IsInputRangeBase<T>::value;
|
||||||
|
|
||||||
// is forward range
|
// is forward range
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, ForwardRangeTag
|
RangeCategory<T>, ForwardRangeTag
|
||||||
>::value> struct IsForwardRangeBase: False {};
|
>::value> struct IsForwardRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsForwardRangeBase<T, true>: True {};
|
struct IsForwardRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsForwardRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsForwardRangeBase<T, true>: detail::IsForwardRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
|
||||||
struct IsForwardRange: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsForwardRange<T, true>: detail::IsForwardRangeBase<T>::Type {};
|
static constexpr bool IsForwardRange = detail::IsForwardRangeBase<T>::value;
|
||||||
|
|
||||||
// is bidirectional range
|
// is bidirectional range
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, BidirectionalRangeTag
|
RangeCategory<T>, BidirectionalRangeTag
|
||||||
>::value> struct IsBidirectionalRangeBase: False {};
|
>::value> struct IsBidirectionalRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsBidirectionalRangeBase<T, true>: True {};
|
struct IsBidirectionalRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsBidirectionalRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsBidirectionalRangeBase<T, true>:
|
||||||
|
detail::IsBidirectionalRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
template<typename T> static constexpr bool IsBidirectionalRange
|
||||||
struct IsBidirectionalRange: False {};
|
= detail::IsBidirectionalRangeBase<T>::value;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsBidirectionalRange<T, true>:
|
|
||||||
detail::IsBidirectionalRangeBase<T>::Type {};
|
|
||||||
|
|
||||||
// is random access range
|
// is random access range
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, RandomAccessRangeTag
|
RangeCategory<T>, RandomAccessRangeTag
|
||||||
>::value> struct IsRandomAccessRangeBase: False {};
|
>::value> struct IsRandomAccessRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsRandomAccessRangeBase<T, true>: True {};
|
struct IsRandomAccessRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsRandomAccessRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsRandomAccessRangeBase<T, true>:
|
||||||
|
detail::IsRandomAccessRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
template<typename T> static constexpr bool IsRandomAccessRange
|
||||||
struct IsRandomAccessRange: False {};
|
= detail::IsRandomAccessRangeBase<T>::value;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsRandomAccessRange<T, true>:
|
|
||||||
detail::IsRandomAccessRangeBase<T>::Type {};
|
|
||||||
|
|
||||||
// is finite random access range
|
// is finite random access range
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, FiniteRandomAccessRangeTag
|
RangeCategory<T>, FiniteRandomAccessRangeTag
|
||||||
>::value> struct IsFiniteRandomAccessRangeBase: False {};
|
>::value> struct IsFiniteRandomAccessRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsFiniteRandomAccessRangeBase<T, true>: True {};
|
struct IsFiniteRandomAccessRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsFiniteRandomAccessRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsFiniteRandomAccessRangeBase<T, true>:
|
||||||
|
detail::IsFiniteRandomAccessRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
template<typename T> static constexpr bool IsFiniteRandomAccessRange
|
||||||
struct IsFiniteRandomAccessRange: False {};
|
= detail::IsFiniteRandomAccessRangeBase<T>::value;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsFiniteRandomAccessRange<T, true>:
|
|
||||||
detail::IsFiniteRandomAccessRangeBase<T>::Type {};
|
|
||||||
|
|
||||||
// is infinite random access range
|
// is infinite random access range
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> static constexpr bool IsInfiniteRandomAccessRange
|
||||||
struct IsInfiniteRandomAccessRange: IntegralConstant<bool,
|
= IsRandomAccessRange<T> && !IsFiniteRandomAccessRange<T>;
|
||||||
(IsRandomAccessRange<T>::value && !IsFiniteRandomAccessRange<T>::value)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
// is contiguous range
|
// is contiguous range
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsConvertible<
|
template<typename T, bool = IsConvertible<
|
||||||
RangeCategory<T>, ContiguousRangeTag
|
RangeCategory<T>, ContiguousRangeTag
|
||||||
>::value> struct IsContiguousRangeBase: False {};
|
>::value> struct IsContiguousRangeCore: False {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsContiguousRangeBase<T, true>: True {};
|
struct IsContiguousRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsContiguousRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsContiguousRangeBase<T, true>:
|
||||||
|
detail::IsContiguousRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = detail::IsRangeTest<T>::value>
|
template<typename T> static constexpr bool IsContiguousRange
|
||||||
struct IsContiguousRange: False {};
|
= detail::IsContiguousRangeBase<T>::value;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsContiguousRange<T, true>:
|
|
||||||
detail::IsContiguousRangeBase<T>::Type {};
|
|
||||||
|
|
||||||
// is output range
|
// is output range
|
||||||
|
|
||||||
|
@ -191,18 +207,28 @@ namespace detail {
|
||||||
template<typename U> static int test(...);
|
template<typename U> static int test(...);
|
||||||
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(char));
|
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(char));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, bool = (IsConvertible<
|
||||||
|
RangeCategory<T>, OutputRangeTag
|
||||||
|
>::value || (IsInputRange<T> &&
|
||||||
|
(detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
|
||||||
|
detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
|
||||||
|
detail::OutputRangeTest<T, RangeValue<T> >::value)
|
||||||
|
))> struct IsOutputRangeCore: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsOutputRangeCore<T, true>: True {};
|
||||||
|
|
||||||
|
template<typename T, bool = detail::IsRangeTest<T>::value>
|
||||||
|
struct IsOutputRangeBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsOutputRangeBase<T, true>:
|
||||||
|
detail::IsOutputRangeCore<T>::Type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = (IsConvertible<
|
template<typename T> static constexpr bool IsOutputRange
|
||||||
RangeCategory<T>, OutputRangeTag
|
= detail::IsOutputRangeBase<T>::value;
|
||||||
>::value || (IsInputRange<T>::value &&
|
|
||||||
(detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
|
|
||||||
detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
|
|
||||||
detail::OutputRangeTest<T, RangeValue<T> >::value)
|
|
||||||
))> struct IsOutputRange: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsOutputRange<T, true>: True {};
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// range iterator
|
// range iterator
|
||||||
|
@ -236,7 +262,7 @@ namespace detail {
|
||||||
template<typename T> struct HalfRange;
|
template<typename T> struct HalfRange;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename R, bool = IsBidirectionalRange<typename R::Range>::value>
|
template<typename R, bool = IsBidirectionalRange<typename R::Range>>
|
||||||
struct RangeAdd;
|
struct RangeAdd;
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
|
@ -484,9 +510,8 @@ template<typename B, typename C, typename V, typename R = V &,
|
||||||
return (on - n);
|
return (on - n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OR,
|
template<typename OR, typename = EnableIf<IsOutputRange<OR>>>
|
||||||
typename = EnableIf<IsOutputRange<OR>::value>
|
Size copy(OR &&orange, Size n = -1) {
|
||||||
> Size copy(OR &&orange, Size n = -1) {
|
|
||||||
B r(*((B *)this));
|
B r(*((B *)this));
|
||||||
Size on = n;
|
Size on = n;
|
||||||
for (; n && !r.empty(); --n) {
|
for (; n && !r.empty(); --n) {
|
||||||
|
@ -995,9 +1020,8 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R,
|
template<typename R, typename = EnableIf<IsOutputRange<R>>>
|
||||||
typename = EnableIf<IsOutputRange<R>::value
|
Size copy(R &&orange, Size n = -1) {
|
||||||
>> Size copy(R &&orange, Size n = -1) {
|
|
||||||
Size c = size();
|
Size c = size();
|
||||||
if (n < c) c = n;
|
if (n < c) c = n;
|
||||||
return orange.put_n(p_beg, c);
|
return orange.put_n(p_beg, c);
|
||||||
|
|
|
@ -75,8 +75,7 @@ namespace detail {
|
||||||
SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> SetImpl(R range, Size size = 0, const H &hf = H(),
|
>> SetImpl(R range, Size size = 0, const H &hf = H(),
|
||||||
const C &eqf = C(), const A &alloc = A()
|
const C &eqf = C(), const A &alloc = A()
|
||||||
): Base(size ? size : detail::estimate_hrsize(range),
|
): Base(size ? size : detail::estimate_hrsize(range),
|
||||||
|
@ -116,8 +115,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> SetImpl &operator=(R range) {
|
>> SetImpl &operator=(R range) {
|
||||||
Base::assign_range(range);
|
Base::assign_range(range);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -209,8 +209,7 @@ class StringBase {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
IsFiniteRandomAccessRange<R>::value &&
|
IsFiniteRandomAccessRange<R> && IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
||||||
IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
|
||||||
> = true) {
|
> = true) {
|
||||||
if (range.empty()) return;
|
if (range.empty()) return;
|
||||||
RangeSize<R> l = range.size();
|
RangeSize<R> l = range.size();
|
||||||
|
@ -222,8 +221,8 @@ class StringBase {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
!IsFiniteRandomAccessRange<R>::value ||
|
!IsFiniteRandomAccessRange<R> || !IsSame<T, RemoveCv<RangeValue<R>>>,
|
||||||
!IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
bool
|
||||||
> = true) {
|
> = true) {
|
||||||
if (range.empty()) return;
|
if (range.empty()) return;
|
||||||
Size i = 0;
|
Size i = 0;
|
||||||
|
@ -327,8 +326,7 @@ public:
|
||||||
> &a = A()): StringBase(ConstRange(v), a) {}
|
> &a = A()): StringBase(ConstRange(v), a) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> StringBase(R range, const A &a = A()): StringBase(a) {
|
>> StringBase(R range, const A &a = A()): StringBase(a) {
|
||||||
ctor_from_range(range);
|
ctor_from_range(range);
|
||||||
}
|
}
|
||||||
|
@ -400,8 +398,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> StringBase &operator=(const R &r) {
|
>> StringBase &operator=(const R &r) {
|
||||||
clear();
|
clear();
|
||||||
ctor_from_range(r);
|
ctor_from_range(r);
|
||||||
|
@ -503,7 +500,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> &&
|
||||||
IsConvertible<RangeReference<R>, Value>::value &&
|
IsConvertible<RangeReference<R>, Value>::value &&
|
||||||
!IsConvertible<R, ConstRange>::value
|
!IsConvertible<R, ConstRange>::value
|
||||||
>> StringBase &append(R range) {
|
>> StringBase &append(R range) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Vector {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
IsFiniteRandomAccessRange<R>::value && IsPod<T> &&
|
IsFiniteRandomAccessRange<R> && IsPod<T> &&
|
||||||
IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
RangeSize<R> l = range.size();
|
RangeSize<R> l = range.size();
|
||||||
|
@ -46,7 +46,7 @@ class Vector {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
!IsFiniteRandomAccessRange<R>::value || !IsPod<T> ||
|
!IsFiniteRandomAccessRange<R> || !IsPod<T> ||
|
||||||
!IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
!IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
Size i = 0;
|
Size i = 0;
|
||||||
|
@ -151,8 +151,7 @@ public:
|
||||||
Vector(ConstRange(v.begin(), v.size()), a) {}
|
Vector(ConstRange(v.begin(), v.size()), a) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> Vector(R range, const A &a = A()): Vector(a) {
|
>> Vector(R range, const A &a = A()): Vector(a) {
|
||||||
ctor_from_range(range);
|
ctor_from_range(range);
|
||||||
}
|
}
|
||||||
|
@ -219,8 +218,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R>::value &&
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>::value
|
||||||
IsConvertible<RangeReference<R>, Value>::value
|
|
||||||
>> Vector &operator=(R range) {
|
>> Vector &operator=(R range) {
|
||||||
clear();
|
clear();
|
||||||
ctor_from_range(range);
|
ctor_from_range(range);
|
||||||
|
|
Loading…
Reference in a new issue