forked from OctaForge/libostd
use standard vector and move/forward
This commit is contained in:
parent
3a21c86a7e
commit
56a3327dce
|
@ -41,7 +41,7 @@ struct Bar {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Vector<int> x = { 5, 10, 15, 20 };
|
std::vector<int> x = { 5, 10, 15, 20 };
|
||||||
writefln("[%(%s|%)]", x);
|
writefln("[%(%s|%)]", x);
|
||||||
|
|
||||||
int y[] = { 2, 4, 8, 16, 32 };
|
int y[] = { 2, 4, 8, 16, 32 };
|
||||||
|
|
|
@ -81,7 +81,7 @@ int main() {
|
||||||
/* "list comprehensions" */
|
/* "list comprehensions" */
|
||||||
writeln("list initialization");
|
writeln("list initialization");
|
||||||
|
|
||||||
Vector<int> test(
|
auto test = make_vector(
|
||||||
range(20)
|
range(20)
|
||||||
| filter([](int v) { return v % 2 == 0; })
|
| filter([](int v) { return v % 2 == 0; })
|
||||||
| map ([](int v) { return v * 2; })
|
| map ([](int v) { return v * 2; })
|
||||||
|
|
|
@ -31,8 +31,10 @@ inline R partition(R range, U pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto partition(F &&func) {
|
inline auto partition(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return partition(forward<decltype(obj)>(obj), forward<F>(func));
|
return partition(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<F>(func)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +51,10 @@ inline bool is_partitioned(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto is_partitioned(F &&func) {
|
inline auto is_partitioned(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return is_partitioned(forward<decltype(obj)>(obj), forward<F>(func));
|
return is_partitioned(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<F>(func)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +66,12 @@ namespace detail {
|
||||||
RangeSize<R> rlen = range.size();
|
RangeSize<R> rlen = range.size();
|
||||||
for (RangeSize<R> i = 1; i < rlen; ++i) {
|
for (RangeSize<R> i = 1; i < rlen; ++i) {
|
||||||
RangeSize<R> j = i;
|
RangeSize<R> j = i;
|
||||||
RangeValue<R> v(move(range[i]));
|
RangeValue<R> v(std::move(range[i]));
|
||||||
while (j > 0 && !compare(range[j - 1], v)) {
|
while (j > 0 && !compare(range[j - 1], v)) {
|
||||||
range[j] = range[j - 1];
|
range[j] = range[j - 1];
|
||||||
--j;
|
--j;
|
||||||
}
|
}
|
||||||
range[j] = move(v);
|
range[j] = std::move(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +158,10 @@ inline R sort_cmp(R range, C compare) {
|
||||||
}
|
}
|
||||||
template<typename C>
|
template<typename C>
|
||||||
inline auto sort_cmp(C &&compare) {
|
inline auto sort_cmp(C &&compare) {
|
||||||
return [compare = forward<C>(compare)](auto &&obj) mutable {
|
return [compare = std::forward<C>(compare)](auto &&obj) mutable {
|
||||||
return sort_cmp(forward<decltype(obj)>(obj), forward<C>(compare));
|
return sort_cmp(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<C>(compare)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +170,7 @@ inline R sort(R range) {
|
||||||
return sort_cmp(range, Less<RangeValue<R>>());
|
return sort_cmp(range, Less<RangeValue<R>>());
|
||||||
}
|
}
|
||||||
inline auto sort() {
|
inline auto sort() {
|
||||||
return [](auto &&obj) { return sort(forward<decltype(obj)>(obj)); };
|
return [](auto &&obj) { return sort(std::forward<decltype(obj)>(obj)); };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* min/max(_element) */
|
/* min/max(_element) */
|
||||||
|
@ -208,12 +214,16 @@ inline R min_element_cmp(R range, C compare) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
inline auto min_element() {
|
inline auto min_element() {
|
||||||
return [](auto &&obj) { return min_element(forward<decltype(obj)>(obj)); };
|
return [](auto &&obj) {
|
||||||
|
return min_element(std::forward<decltype(obj)>(obj));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
template<typename C>
|
template<typename C>
|
||||||
inline auto min_element_cmp(C &&compare) {
|
inline auto min_element_cmp(C &&compare) {
|
||||||
return [compare = forward<C>(compare)](auto &&obj) mutable {
|
return [compare = std::forward<C>(compare)](auto &&obj) mutable {
|
||||||
return min_element_cmp(forward<decltype(obj)>(obj), forward<C>(compare));
|
return min_element_cmp(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<C>(compare)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,12 +248,16 @@ inline R max_element_cmp(R range, C compare) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
inline auto max_element() {
|
inline auto max_element() {
|
||||||
return [](auto &&obj) { return max_element(forward<decltype(obj)>(obj)); };
|
return [](auto &&obj) {
|
||||||
|
return max_element(std::forward<decltype(obj)>(obj));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
template<typename C>
|
template<typename C>
|
||||||
inline auto max_element_cmp(C &&compare) {
|
inline auto max_element_cmp(C &&compare) {
|
||||||
return [compare = forward<C>(compare)](auto &&obj) mutable {
|
return [compare = std::forward<C>(compare)](auto &&obj) mutable {
|
||||||
return max_element_cmp(forward<decltype(obj)>(obj), forward<C>(compare));
|
return max_element_cmp(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<C>(compare)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,9 +310,9 @@ inline bool lexicographical_compare(R1 range1, R2 range2) {
|
||||||
}
|
}
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto lexicographical_compare(R &&range) {
|
inline auto lexicographical_compare(R &&range) {
|
||||||
return [range = forward<R>(range)](auto &&obj) mutable {
|
return [range = std::forward<R>(range)](auto &&obj) mutable {
|
||||||
return lexicographical_compare(
|
return lexicographical_compare(
|
||||||
forward<decltype(obj)>(obj), forward<R>(range)
|
std::forward<decltype(obj)>(obj), std::forward<R>(range)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -320,10 +334,11 @@ inline bool lexicographical_compare_cmp(R1 range1, R2 range2, C compare) {
|
||||||
template<typename R, typename C>
|
template<typename R, typename C>
|
||||||
inline auto lexicographical_compare_cmp(R &&range, C &&compare) {
|
inline auto lexicographical_compare_cmp(R &&range, C &&compare) {
|
||||||
return [
|
return [
|
||||||
range = forward<R>(range), compare = forward<C>(compare)
|
range = std::forward<R>(range), compare = std::forward<C>(compare)
|
||||||
](auto &&obj) mutable {
|
](auto &&obj) mutable {
|
||||||
return lexicographical_compare_cmp(
|
return lexicographical_compare_cmp(
|
||||||
forward<decltype(obj)>(obj), forward<R>(range), forward<C>(compare)
|
std::forward<decltype(obj)>(obj), std::forward<R>(range),
|
||||||
|
std::forward<C>(compare)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -335,13 +350,13 @@ inline F for_each(R range, F func) {
|
||||||
for (; !range.empty(); range.pop_front()) {
|
for (; !range.empty(); range.pop_front()) {
|
||||||
func(range.front());
|
func(range.front());
|
||||||
}
|
}
|
||||||
return move(func);
|
return std::move(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto for_each(F &&func) {
|
inline auto for_each(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return for_each(forward<decltype(obj)>(obj), forward<F>(func));
|
return for_each(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,8 +372,8 @@ inline bool all_of(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto all_of(F &&func) {
|
inline auto all_of(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return all_of(forward<decltype(obj)>(obj), forward<F>(func));
|
return all_of(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +386,8 @@ inline bool any_of(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto any_of(F &&func) {
|
inline auto any_of(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return any_of(forward<decltype(obj)>(obj), forward<F>(func));
|
return any_of(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,8 +400,8 @@ inline bool none_of(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto none_of(F &&func) {
|
inline auto none_of(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return none_of(forward<decltype(obj)>(obj), forward<F>(func));
|
return none_of(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,8 +417,8 @@ inline R find(R range, T const &v) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline auto find(T &&v) {
|
inline auto find(T &&v) {
|
||||||
return [v = forward<T>(v)](auto &&obj) mutable {
|
return [v = std::forward<T>(v)](auto &&obj) mutable {
|
||||||
return find(forward<decltype(obj)>(obj), forward<T>(v));
|
return find(std::forward<decltype(obj)>(obj), std::forward<T>(v));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,8 +441,8 @@ inline R find_last(R range, T const &v) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline auto find_last(T &&v) {
|
inline auto find_last(T &&v) {
|
||||||
return [v = forward<T>(v)](auto &&obj) mutable {
|
return [v = std::forward<T>(v)](auto &&obj) mutable {
|
||||||
return find_last(forward<decltype(obj)>(obj), forward<T>(v));
|
return find_last(std::forward<decltype(obj)>(obj), std::forward<T>(v));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,8 +458,8 @@ inline R find_if(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto find_if(F &&func) {
|
inline auto find_if(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return find_if(forward<decltype(obj)>(obj), forward<F>(func));
|
return find_if(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,8 +475,10 @@ inline R find_if_not(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto find_if_not(F &&func) {
|
inline auto find_if_not(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return find_if_not(forward<decltype(obj)>(obj), forward<F>(func));
|
return find_if_not(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<F>(func)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,10 +496,11 @@ inline R1 find_one_of_cmp(R1 range, R2 values, C compare) {
|
||||||
template<typename R, typename C>
|
template<typename R, typename C>
|
||||||
inline auto find_one_of_cmp(R &&values, C &&compare) {
|
inline auto find_one_of_cmp(R &&values, C &&compare) {
|
||||||
return [
|
return [
|
||||||
values = forward<R>(values), compare = forward<C>(compare)
|
values = std::forward<R>(values), compare = std::forward<C>(compare)
|
||||||
](auto &&obj) mutable {
|
](auto &&obj) mutable {
|
||||||
return find_one_of_cmp(
|
return find_one_of_cmp(
|
||||||
forward<decltype(obj)>(obj), forward<R>(values), forward<C>(compare)
|
std::forward<decltype(obj)>(obj), std::forward<R>(values),
|
||||||
|
std::forward<C>(compare)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -500,8 +518,10 @@ inline R1 find_one_of(R1 range, R2 values) {
|
||||||
}
|
}
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto find_one_of(R &&values) {
|
inline auto find_one_of(R &&values) {
|
||||||
return [values = forward<R>(values)](auto &&obj) mutable {
|
return [values = std::forward<R>(values)](auto &&obj) mutable {
|
||||||
return find_one_of(forward<decltype(obj)>(obj), forward<R>(values));
|
return find_one_of(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<R>(values)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,8 +538,8 @@ inline RangeSize<R> count(R range, T const &v) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline auto count(T &&v) {
|
inline auto count(T &&v) {
|
||||||
return [v = forward<T>(v)](auto &&obj) mutable {
|
return [v = std::forward<T>(v)](auto &&obj) mutable {
|
||||||
return count(forward<decltype(obj)>(obj), forward<T>(v));
|
return count(std::forward<decltype(obj)>(obj), std::forward<T>(v));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,8 +556,8 @@ inline RangeSize<R> count_if(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto count_if(F &&func) {
|
inline auto count_if(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return count_if(forward<decltype(obj)>(obj), forward<F>(func));
|
return count_if(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,8 +574,10 @@ inline RangeSize<R> count_if_not(R range, P pred) {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto count_if_not(F &&func) {
|
inline auto count_if_not(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return count_if_not(forward<decltype(obj)>(obj), forward<F>(func));
|
return count_if_not(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<F>(func)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,8 +594,8 @@ inline bool equal(R range1, R range2) {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto equal(R &&range) {
|
inline auto equal(R &&range) {
|
||||||
return [range = forward<R>(range)](auto &&obj) mutable {
|
return [range = std::forward<R>(range)](auto &&obj) mutable {
|
||||||
return equal(forward<decltype(obj)>(obj), forward<R>(range));
|
return equal(std::forward<decltype(obj)>(obj), std::forward<R>(range));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,8 +606,10 @@ R slice_until(R range1, R range2) {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto slice_until(R &&range) {
|
inline auto slice_until(R &&range) {
|
||||||
return [range = forward<R>(range)](auto &&obj) mutable {
|
return [range = std::forward<R>(range)](auto &&obj) mutable {
|
||||||
return slice_until(forward<decltype(obj)>(obj), forward<R>(range));
|
return slice_until(
|
||||||
|
std::forward<decltype(obj)>(obj), std::forward<R>(range)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +646,7 @@ inline R2 copy_if_not(R1 irange, R2 orange, P pred) {
|
||||||
template<typename R1, typename R2>
|
template<typename R1, typename R2>
|
||||||
inline R2 move(R1 irange, R2 orange) {
|
inline R2 move(R1 irange, R2 orange) {
|
||||||
for (; !irange.empty(); irange.pop_front()) {
|
for (; !irange.empty(); irange.pop_front()) {
|
||||||
orange.put(move(irange.front()));
|
orange.put(std::move(irange.front()));
|
||||||
}
|
}
|
||||||
return orange;
|
return orange;
|
||||||
}
|
}
|
||||||
|
@ -693,17 +717,18 @@ inline T foldl_f(R range, T init, F func) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline auto foldl(T &&init) {
|
inline auto foldl(T &&init) {
|
||||||
return [init = forward<T>(init)](auto &&obj) mutable {
|
return [init = std::forward<T>(init)](auto &&obj) mutable {
|
||||||
return foldl(forward<decltype(obj)>(obj), forward<T>(init));
|
return foldl(std::forward<decltype(obj)>(obj), std::forward<T>(init));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template<typename T, typename F>
|
template<typename T, typename F>
|
||||||
inline auto foldl_f(T &&init, F &&func) {
|
inline auto foldl_f(T &&init, F &&func) {
|
||||||
return [
|
return [
|
||||||
init = forward<T>(init), func = forward<F>(func)
|
init = std::forward<T>(init), func = std::forward<F>(func)
|
||||||
](auto &&obj) mutable {
|
](auto &&obj) mutable {
|
||||||
return foldl_f(
|
return foldl_f(
|
||||||
forward<decltype(obj)>(obj), forward<T>(init), forward<F>(func)
|
std::forward<decltype(obj)>(obj), std::forward<T>(init),
|
||||||
|
std::forward<F>(func)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -726,17 +751,18 @@ inline T foldr_f(R range, T init, F func) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline auto foldr(T &&init) {
|
inline auto foldr(T &&init) {
|
||||||
return [init = forward<T>(init)](auto &&obj) mutable {
|
return [init = std::forward<T>(init)](auto &&obj) mutable {
|
||||||
return foldr(forward<decltype(obj)>(obj), forward<T>(init));
|
return foldr(std::forward<decltype(obj)>(obj), std::forward<T>(init));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template<typename T, typename F>
|
template<typename T, typename F>
|
||||||
inline auto foldr_f(T &&init, F &&func) {
|
inline auto foldr_f(T &&init, F &&func) {
|
||||||
return [
|
return [
|
||||||
init = forward<T>(init), func = forward<F>(func)
|
init = std::forward<T>(init), func = std::forward<F>(func)
|
||||||
](auto &&obj) mutable {
|
](auto &&obj) mutable {
|
||||||
return foldr_f(
|
return foldr_f(
|
||||||
forward<decltype(obj)>(obj), forward<T>(init), forward<F>(func)
|
std::forward<decltype(obj)>(obj), std::forward<T>(init),
|
||||||
|
std::forward<F>(func)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -753,11 +779,11 @@ public:
|
||||||
MapRange() = delete;
|
MapRange() = delete;
|
||||||
template<typename FF>
|
template<typename FF>
|
||||||
MapRange(T const &range, FF &&func):
|
MapRange(T const &range, FF &&func):
|
||||||
p_range(range), p_func(forward<FF>(func)) {}
|
p_range(range), p_func(std::forward<FF>(func)) {}
|
||||||
MapRange(MapRange const &it):
|
MapRange(MapRange const &it):
|
||||||
p_range(it.p_range), p_func(it.p_func) {}
|
p_range(it.p_range), p_func(it.p_func) {}
|
||||||
MapRange(MapRange &&it):
|
MapRange(MapRange &&it):
|
||||||
p_range(move(it.p_range)), p_func(move(it.p_func)) {}
|
p_range(std::move(it.p_range)), p_func(std::move(it.p_func)) {}
|
||||||
|
|
||||||
MapRange &operator=(MapRange const &v) {
|
MapRange &operator=(MapRange const &v) {
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
|
@ -765,8 +791,8 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MapRange &operator=(MapRange &&v) {
|
MapRange &operator=(MapRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
p_func = move(v.p_func);
|
p_func = std::move(v.p_func);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,13 +852,13 @@ namespace detail {
|
||||||
|
|
||||||
template<typename R, typename F>
|
template<typename R, typename F>
|
||||||
inline MapRange<R, F, detail::MapReturnType<R, F>> map(R range, F func) {
|
inline MapRange<R, F, detail::MapReturnType<R, F>> map(R range, F func) {
|
||||||
return MapRange<R, F, detail::MapReturnType<R, F>>(range, move(func));
|
return MapRange<R, F, detail::MapReturnType<R, F>>(range, std::move(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto map(F &&func) {
|
inline auto map(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return map(forward<decltype(obj)>(obj), forward<F>(func));
|
return map(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,7 +881,7 @@ public:
|
||||||
FilterRange() = delete;
|
FilterRange() = delete;
|
||||||
template<typename P>
|
template<typename P>
|
||||||
FilterRange(T const &range, P &&pred):
|
FilterRange(T const &range, P &&pred):
|
||||||
p_range(range), p_pred(forward<P>(pred))
|
p_range(range), p_pred(std::forward<P>(pred))
|
||||||
{
|
{
|
||||||
advance_valid();
|
advance_valid();
|
||||||
}
|
}
|
||||||
|
@ -865,7 +891,7 @@ public:
|
||||||
advance_valid();
|
advance_valid();
|
||||||
}
|
}
|
||||||
FilterRange(FilterRange &&it):
|
FilterRange(FilterRange &&it):
|
||||||
p_range(move(it.p_range)), p_pred(move(it.p_pred))
|
p_range(std::move(it.p_range)), p_pred(std::move(it.p_pred))
|
||||||
{
|
{
|
||||||
advance_valid();
|
advance_valid();
|
||||||
}
|
}
|
||||||
|
@ -877,8 +903,8 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
FilterRange &operator=(FilterRange &&v) {
|
FilterRange &operator=(FilterRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
p_pred = move(v.p_pred);
|
p_pred = std::move(v.p_pred);
|
||||||
advance_valid();
|
advance_valid();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -907,13 +933,13 @@ namespace detail {
|
||||||
|
|
||||||
template<typename R, typename P>
|
template<typename R, typename P>
|
||||||
inline FilterRange<R, detail::FilterPred<R, P>> filter(R range, P pred) {
|
inline FilterRange<R, detail::FilterPred<R, P>> filter(R range, P pred) {
|
||||||
return FilterRange<R, P>(range, move(pred));
|
return FilterRange<R, P>(range, std::move(pred));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline auto filter(F &&func) {
|
inline auto filter(F &&func) {
|
||||||
return [func = forward<F>(func)](auto &&obj) mutable {
|
return [func = std::forward<F>(func)](auto &&obj) mutable {
|
||||||
return filter(forward<decltype(obj)>(obj), forward<F>(func));
|
return filter(std::forward<decltype(obj)>(obj), std::forward<F>(func));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,12 +103,12 @@ inline TupleElement<I, Array<T, N>> const &get(Array<T, N> const &a) noexcept {
|
||||||
|
|
||||||
template<Size I, typename T, Size N>
|
template<Size I, typename T, Size N>
|
||||||
inline TupleElement<I, Array<T, N>> &&get(Array<T, N> &&a) noexcept {
|
inline TupleElement<I, Array<T, N>> &&get(Array<T, N> &&a) noexcept {
|
||||||
return move(a.p_buf[I]);
|
return std::move(a.p_buf[I]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Size I, typename T, Size N>
|
template<Size I, typename T, Size N>
|
||||||
inline TupleElement<I, Array<T, N>> const &&get(Array<T, N> const &&a) noexcept {
|
inline TupleElement<I, Array<T, N>> const &&get(Array<T, N> const &&a) noexcept {
|
||||||
return move(a.p_buf[I]);
|
return std::move(a.p_buf[I]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, Size N>
|
template<typename T, Size N>
|
||||||
|
|
|
@ -27,7 +27,7 @@ inline Maybe<String> env_get(ConstCharRange name) {
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return ostd::nothing;
|
return ostd::nothing;
|
||||||
}
|
}
|
||||||
return ostd::move(String(ret));
|
return std::move(String(ret));
|
||||||
#else
|
#else
|
||||||
String rbuf;
|
String rbuf;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -43,7 +43,7 @@ inline Maybe<String> env_get(ConstCharRange name) {
|
||||||
}
|
}
|
||||||
rbuf.reserve(ret - 1);
|
rbuf.reserve(ret - 1);
|
||||||
}
|
}
|
||||||
return ostd::move(rbuf);
|
return std::move(rbuf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,17 +67,17 @@ namespace detail {
|
||||||
using Func = Function<void(C &, A...)>;
|
using Func = Function<void(C &, A...)>;
|
||||||
for (Size i = 0; i < p_nfuncs; ++i) {
|
for (Size i = 0; i < p_nfuncs; ++i) {
|
||||||
if (!p_funcs[i]) {
|
if (!p_funcs[i]) {
|
||||||
p_funcs[i] = forward<F>(func);
|
p_funcs[i] = std::forward<F>(func);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
byte *bufp = new byte[sizeof(Func) * (p_nfuncs + 1)];
|
byte *bufp = new byte[sizeof(Func) * (p_nfuncs + 1)];
|
||||||
Func *nbuf = reinterpret_cast<Func *>(bufp);
|
Func *nbuf = reinterpret_cast<Func *>(bufp);
|
||||||
for (Size i = 0; i < p_nfuncs; ++i) {
|
for (Size i = 0; i < p_nfuncs; ++i) {
|
||||||
new (&nbuf[i]) Func(move(p_funcs[i]));
|
new (&nbuf[i]) Func(std::move(p_funcs[i]));
|
||||||
p_funcs[i].~Func();
|
p_funcs[i].~Func();
|
||||||
}
|
}
|
||||||
new (&nbuf[p_nfuncs]) Func(forward<F>(func));
|
new (&nbuf[p_nfuncs]) Func(std::forward<F>(func));
|
||||||
delete[] reinterpret_cast<byte *>(p_funcs);
|
delete[] reinterpret_cast<byte *>(p_funcs);
|
||||||
p_funcs = nbuf;
|
p_funcs = nbuf;
|
||||||
return p_nfuncs++;
|
return p_nfuncs++;
|
||||||
|
@ -134,7 +134,7 @@ private:
|
||||||
public:
|
public:
|
||||||
Signal(C *cl): p_base(cl) {}
|
Signal(C *cl): p_base(cl) {}
|
||||||
Signal(Signal const &ev): p_base(ev.p_base) {}
|
Signal(Signal const &ev): p_base(ev.p_base) {}
|
||||||
Signal(Signal &&ev): p_base(move(ev.p_base)) {}
|
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {}
|
||||||
|
|
||||||
Signal &operator=(Signal const &ev) {
|
Signal &operator=(Signal const &ev) {
|
||||||
p_base = ev.p_base;
|
p_base = ev.p_base;
|
||||||
|
@ -142,22 +142,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal &operator=(Signal &&ev) {
|
Signal &operator=(Signal &&ev) {
|
||||||
p_base = move(ev.p_base);
|
p_base = std::move(ev.p_base);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() { p_base.clear(); }
|
void clear() { p_base.clear(); }
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Size connect(F &&func) { return p_base.connect(forward<F>(func)); }
|
Size connect(F &&func) { return p_base.connect(std::forward<F>(func)); }
|
||||||
|
|
||||||
bool disconnect(Size idx) { return p_base.disconnect(idx); }
|
bool disconnect(Size idx) { return p_base.disconnect(idx); }
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
void emit(Args &&...args) { p_base.emit(forward<Args>(args)...); }
|
void emit(Args &&...args) { p_base.emit(std::forward<Args>(args)...); }
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
void operator()(Args &&...args) { emit(forward<Args>(args)...); }
|
void operator()(Args &&...args) { emit(std::forward<Args>(args)...); }
|
||||||
|
|
||||||
C *get_class() const { return p_base.get_class(); }
|
C *get_class() const { return p_base.get_class(); }
|
||||||
C *set_class(C *cl) { return p_base.set_class(cl); }
|
C *set_class(C *cl) { return p_base.set_class(cl); }
|
||||||
|
@ -173,7 +173,7 @@ private:
|
||||||
public:
|
public:
|
||||||
Signal(C *cl): p_base(cl) {}
|
Signal(C *cl): p_base(cl) {}
|
||||||
Signal(Signal const &ev): p_base(ev.p_base) {}
|
Signal(Signal const &ev): p_base(ev.p_base) {}
|
||||||
Signal(Signal &&ev): p_base(move(ev.p_base)) {}
|
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {}
|
||||||
|
|
||||||
Signal &operator=(Signal const &ev) {
|
Signal &operator=(Signal const &ev) {
|
||||||
p_base = ev.p_base;
|
p_base = ev.p_base;
|
||||||
|
@ -181,22 +181,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal &operator=(Signal &&ev) {
|
Signal &operator=(Signal &&ev) {
|
||||||
p_base = move(ev.p_base);
|
p_base = std::move(ev.p_base);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() { p_base.clear(); }
|
void clear() { p_base.clear(); }
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Size connect(F &&func) { return p_base.connect(forward<F>(func)); }
|
Size connect(F &&func) { return p_base.connect(std::forward<F>(func)); }
|
||||||
|
|
||||||
bool disconnect(Size idx) { return p_base.disconnect(idx); }
|
bool disconnect(Size idx) { return p_base.disconnect(idx); }
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
void emit(Args &&...args) const { p_base.emit(forward<Args>(args)...); }
|
void emit(Args &&...args) const { p_base.emit(std::forward<Args>(args)...); }
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
void operator()(Args &&...args) const { emit(forward<Args>(args)...); }
|
void operator()(Args &&...args) const { emit(std::forward<Args>(args)...); }
|
||||||
|
|
||||||
C *get_class() const { return p_base.get_class(); }
|
C *get_class() const { return p_base.get_class(); }
|
||||||
C *set_class(C *cl) { return p_base.set_class(cl); }
|
C *set_class(C *cl) { return p_base.set_class(cl); }
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct FileInfo {
|
||||||
|
|
||||||
FileInfo(FileInfo &&i):
|
FileInfo(FileInfo &&i):
|
||||||
p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type),
|
p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type),
|
||||||
p_path(move(i.p_path)), p_atime(i.p_atime), p_mtime(i.p_mtime),
|
p_path(std::move(i.p_path)), p_atime(i.p_atime), p_mtime(i.p_mtime),
|
||||||
p_ctime(i.p_ctime)
|
p_ctime(i.p_ctime)
|
||||||
{
|
{
|
||||||
i.p_slash = i.p_dot = npos;
|
i.p_slash = i.p_dot = npos;
|
||||||
|
@ -228,7 +228,7 @@ struct DirectoryStream {
|
||||||
DirectoryStream(): p_d(), p_de(), p_path() {}
|
DirectoryStream(): p_d(), p_de(), p_path() {}
|
||||||
DirectoryStream(DirectoryStream const &) = delete;
|
DirectoryStream(DirectoryStream const &) = delete;
|
||||||
DirectoryStream(DirectoryStream &&s):
|
DirectoryStream(DirectoryStream &&s):
|
||||||
p_d(s.p_d), p_de(s.p_de), p_path(move(s.p_path))
|
p_d(s.p_d), p_de(s.p_de), p_path(std::move(s.p_path))
|
||||||
{
|
{
|
||||||
s.p_d = nullptr;
|
s.p_d = nullptr;
|
||||||
s.p_de = nullptr;
|
s.p_de = nullptr;
|
||||||
|
@ -364,7 +364,7 @@ struct DirectoryStream {
|
||||||
DirectoryStream(): p_handle(INVALID_HANDLE_VALUE), p_data(), p_path() {}
|
DirectoryStream(): p_handle(INVALID_HANDLE_VALUE), p_data(), p_path() {}
|
||||||
DirectoryStream(DirectoryStream const &) = delete;
|
DirectoryStream(DirectoryStream const &) = delete;
|
||||||
DirectoryStream(DirectoryStream &&s):
|
DirectoryStream(DirectoryStream &&s):
|
||||||
p_handle(s.p_handle), p_data(s.p_data), p_path(move(s.p_path))
|
p_handle(s.p_handle), p_data(s.p_data), p_path(std::move(s.p_path))
|
||||||
{
|
{
|
||||||
s.p_handle = INVALID_HANDLE_VALUE;
|
s.p_handle = INVALID_HANDLE_VALUE;
|
||||||
memset(&s.p_data, 0, sizeof(s.p_data));
|
memset(&s.p_data, 0, sizeof(s.p_data));
|
||||||
|
|
|
@ -509,14 +509,6 @@ namespace detail {
|
||||||
ConstCharRange fmt, A const &...args
|
ConstCharRange fmt, A const &...args
|
||||||
);
|
);
|
||||||
|
|
||||||
template<typename T, typename = RangeOf<T>>
|
|
||||||
static True test_fmt_range(int);
|
|
||||||
template<typename>
|
|
||||||
static False test_fmt_range(...);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool FmtRangeTest = decltype(test_fmt_range<T>(0))::value;
|
|
||||||
|
|
||||||
template<Size I>
|
template<Size I>
|
||||||
struct FmtTupleUnpacker {
|
struct FmtTupleUnpacker {
|
||||||
template<typename R, typename T, typename ...A>
|
template<typename R, typename T, typename ...A>
|
||||||
|
@ -565,7 +557,7 @@ namespace detail {
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
inline Ptrdiff write_range(
|
inline Ptrdiff write_range(
|
||||||
R &writer, FormatSpec const *fl, bool escape, bool expandval,
|
R &writer, FormatSpec const *fl, bool escape, bool expandval,
|
||||||
ConstCharRange sep, T const &val, EnableIf<FmtRangeTest<T>, bool> = true
|
ConstCharRange sep, T const &val, EnableIf<detail::IterableTest<T>, bool> = true
|
||||||
) {
|
) {
|
||||||
auto range = ostd::iter(val);
|
auto range = ostd::iter(val);
|
||||||
if (range.empty()) {
|
if (range.empty()) {
|
||||||
|
@ -603,7 +595,7 @@ namespace detail {
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
inline Ptrdiff write_range(
|
inline Ptrdiff write_range(
|
||||||
R &, FormatSpec const *, bool, bool, ConstCharRange,
|
R &, FormatSpec const *, bool, bool, ConstCharRange,
|
||||||
T const &, EnableIf<!FmtRangeTest<T>, bool> = true
|
T const &, EnableIf<!detail::IterableTest<T>, bool> = true
|
||||||
) {
|
) {
|
||||||
assert(false && "invalid value for ranged format");
|
assert(false && "invalid value for ranged format");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -514,27 +514,27 @@ namespace detail {
|
||||||
MemFn(R T::*ptr): p_ptr(ptr) {}
|
MemFn(R T::*ptr): p_ptr(ptr) {}
|
||||||
template<typename... A>
|
template<typename... A>
|
||||||
auto operator()(T &obj, A &&...args) ->
|
auto operator()(T &obj, A &&...args) ->
|
||||||
decltype(((obj).*(p_ptr))(forward<A>(args)...))
|
decltype(((obj).*(p_ptr))(std::forward<A>(args)...))
|
||||||
{
|
{
|
||||||
return ((obj).*(p_ptr))(forward<A>(args)...);
|
return ((obj).*(p_ptr))(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
template<typename... A>
|
template<typename... A>
|
||||||
auto operator()(T const &obj, A &&...args) ->
|
auto operator()(T const &obj, A &&...args) ->
|
||||||
decltype(((obj).*(p_ptr))(forward<A>(args)...))
|
decltype(((obj).*(p_ptr))(std::forward<A>(args)...))
|
||||||
const {
|
const {
|
||||||
return ((obj).*(p_ptr))(forward<A>(args)...);
|
return ((obj).*(p_ptr))(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
template<typename... A>
|
template<typename... A>
|
||||||
auto operator()(T *obj, A &&...args) ->
|
auto operator()(T *obj, A &&...args) ->
|
||||||
decltype(((obj)->*(p_ptr))(forward<A>(args)...))
|
decltype(((obj)->*(p_ptr))(std::forward<A>(args)...))
|
||||||
{
|
{
|
||||||
return ((obj)->*(p_ptr))(forward<A>(args)...);
|
return ((obj)->*(p_ptr))(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
template<typename... A>
|
template<typename... A>
|
||||||
auto operator()(T const *obj, A &&...args) ->
|
auto operator()(T const *obj, A &&...args) ->
|
||||||
decltype(((obj)->*(p_ptr))(forward<A>(args)...))
|
decltype(((obj)->*(p_ptr))(std::forward<A>(args)...))
|
||||||
const {
|
const {
|
||||||
return ((obj)->*(p_ptr))(forward<A>(args)...);
|
return ((obj)->*(p_ptr))(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
@ -575,7 +575,7 @@ namespace detail {
|
||||||
struct FuncInvokeVoidReturnWrapper {
|
struct FuncInvokeVoidReturnWrapper {
|
||||||
template<typename ...A>
|
template<typename ...A>
|
||||||
static R call(A &&...args) {
|
static R call(A &&...args) {
|
||||||
return func_invoke(forward<A>(args)...);
|
return func_invoke(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ namespace detail {
|
||||||
struct FuncInvokeVoidReturnWrapper<void> {
|
struct FuncInvokeVoidReturnWrapper<void> {
|
||||||
template<typename ...A>
|
template<typename ...A>
|
||||||
static void call(A &&...args) {
|
static void call(A &&...args) {
|
||||||
func_invoke(forward<A>(args)...);
|
func_invoke(std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ public:
|
||||||
explicit FuncCore(F &&f):
|
explicit FuncCore(F &&f):
|
||||||
f_stor(
|
f_stor(
|
||||||
piecewise_construct,
|
piecewise_construct,
|
||||||
forward_as_tuple(ostd::move(f)),
|
forward_as_tuple(std::move(f)),
|
||||||
forward_as_tuple()
|
forward_as_tuple()
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
@ -631,15 +631,15 @@ public:
|
||||||
f_stor(
|
f_stor(
|
||||||
piecewise_construct,
|
piecewise_construct,
|
||||||
forward_as_tuple(f),
|
forward_as_tuple(f),
|
||||||
forward_as_tuple(ostd::move(a))
|
forward_as_tuple(std::move(a))
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit FuncCore(F &&f, A &&a):
|
explicit FuncCore(F &&f, A &&a):
|
||||||
f_stor(
|
f_stor(
|
||||||
piecewise_construct,
|
piecewise_construct,
|
||||||
forward_as_tuple(ostd::move(f)),
|
forward_as_tuple(std::move(f)),
|
||||||
forward_as_tuple(ostd::move(a))
|
forward_as_tuple(std::move(a))
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ public:
|
||||||
template<typename F, typename A, typename R, typename ...AT>
|
template<typename F, typename A, typename R, typename ...AT>
|
||||||
R FuncCore<F, A, R(AT...)>::operator()(AT &&...args) {
|
R FuncCore<F, A, R(AT...)>::operator()(AT &&...args) {
|
||||||
using Invoker = FuncInvokeVoidReturnWrapper<R>;
|
using Invoker = FuncInvokeVoidReturnWrapper<R>;
|
||||||
return Invoker::call(f_stor.first(), forward<AT>(args)...);
|
return Invoker::call(f_stor.first(), std::forward<AT>(args)...);
|
||||||
}
|
}
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
|
@ -752,7 +752,7 @@ public:
|
||||||
Callable<Decay<F>> && !IsSame<RemoveReference<F>, Function>,
|
Callable<Decay<F>> && !IsSame<RemoveReference<F>, Function>,
|
||||||
Function &
|
Function &
|
||||||
> operator=(F &&f) {
|
> operator=(F &&f) {
|
||||||
Function(forward<F>(f)).swap(*this);
|
Function(std::forward<F>(f)).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,7 +769,7 @@ public:
|
||||||
bool operator!=(Function<RR(AA...)> &) const = delete;
|
bool operator!=(Function<RR(AA...)> &) const = delete;
|
||||||
|
|
||||||
R operator()(Args ...a) const {
|
R operator()(Args ...a) const {
|
||||||
return (*p_f)(forward<Args>(a)...);
|
return (*p_f)(std::forward<Args>(a)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -837,14 +837,14 @@ Function<R(Args...)>::Function(F f): p_f(nullptr) {
|
||||||
}
|
}
|
||||||
using FF = detail::FuncCore<F, Allocator<F>, R(Args...)>;
|
using FF = detail::FuncCore<F, Allocator<F>, R(Args...)>;
|
||||||
if ((sizeof(FF) <= sizeof(p_buf)) && IsNothrowCopyConstructible<F>) {
|
if ((sizeof(FF) <= sizeof(p_buf)) && IsNothrowCopyConstructible<F>) {
|
||||||
p_f = ::new(static_cast<void *>(&p_buf)) FF(move(f));
|
p_f = ::new(static_cast<void *>(&p_buf)) FF(std::move(f));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
using AA = Allocator<FF>;
|
using AA = Allocator<FF>;
|
||||||
AA a;
|
AA a;
|
||||||
using D = detail::AllocatorDestructor<AA>;
|
using D = detail::AllocatorDestructor<AA>;
|
||||||
Box<FF, D> hold(a.allocate(1), D(a, 1));
|
Box<FF, D> hold(a.allocate(1), D(a, 1));
|
||||||
::new(hold.get()) FF(move(f), Allocator<F>(a));
|
::new(hold.get()) FF(std::move(f), Allocator<F>(a));
|
||||||
p_f = hold.release();
|
p_f = hold.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,12 +863,12 @@ Function<R(Args...)>::Function(AllocatorArg, A const &a, F f):
|
||||||
(sizeof(FF) <= sizeof(p_buf)) && IsNothrowCopyConstructible<F> &&
|
(sizeof(FF) <= sizeof(p_buf)) && IsNothrowCopyConstructible<F> &&
|
||||||
IsNothrowCopyConstructible<AA>
|
IsNothrowCopyConstructible<AA>
|
||||||
) {
|
) {
|
||||||
p_f = ::new(static_cast<void *>(&p_buf)) FF(move(f), A(aa));
|
p_f = ::new(static_cast<void *>(&p_buf)) FF(std::move(f), A(aa));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
using D = detail::AllocatorDestructor<AA>;
|
using D = detail::AllocatorDestructor<AA>;
|
||||||
Box<FF, D> hold(aa.allocate(1), D(aa, 1));
|
Box<FF, D> hold(aa.allocate(1), D(aa, 1));
|
||||||
::new(hold.get()) FF(move(f), A(aa));
|
::new(hold.get()) FF(std::move(f), A(aa));
|
||||||
p_f = hold.release();
|
p_f = hold.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ protected:
|
||||||
template<typename U>
|
template<typename U>
|
||||||
T &insert(Size h, U &&key) {
|
T &insert(Size h, U &&key) {
|
||||||
Chain *c = insert(h);
|
Chain *c = insert(h);
|
||||||
B::set_key(c->value, forward<U>(key), get_alloc());
|
B::set_key(c->value, std::forward<U>(key), get_alloc());
|
||||||
return B::get_data(c->value);
|
return B::get_data(c->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ protected:
|
||||||
return B::get_data(c->value);
|
return B::get_data(c->value);
|
||||||
}
|
}
|
||||||
rehash_ahead(1);
|
rehash_ahead(1);
|
||||||
return insert(bucket(key), move(key));
|
return insert(bucket(key), std::move(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
T *access(const K &key) const {
|
T *access(const K &key) const {
|
||||||
|
@ -422,7 +422,7 @@ protected:
|
||||||
|
|
||||||
Hashtable(Hashtable &&ht): p_size(ht.p_size), p_len(ht.p_len),
|
Hashtable(Hashtable &&ht): p_size(ht.p_size), p_len(ht.p_len),
|
||||||
p_chunks(ht.p_chunks), p_unused(ht.p_unused),
|
p_chunks(ht.p_chunks), p_unused(ht.p_unused),
|
||||||
p_data(move(ht.p_data)), p_maxlf(ht.p_maxlf) {
|
p_data(std::move(ht.p_data)), p_maxlf(ht.p_maxlf) {
|
||||||
ht.p_size = ht.p_len = 0;
|
ht.p_size = ht.p_len = 0;
|
||||||
ht.p_chunks = nullptr;
|
ht.p_chunks = nullptr;
|
||||||
ht.p_unused = nullptr;
|
ht.p_unused = nullptr;
|
||||||
|
@ -565,7 +565,7 @@ public:
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
Pair<Range, bool> emplace(Args &&...args) {
|
Pair<Range, bool> emplace(Args &&...args) {
|
||||||
rehash_ahead(1);
|
rehash_ahead(1);
|
||||||
E elem(forward<Args>(args)...);
|
E elem(std::forward<Args>(args)...);
|
||||||
if (Multihash) {
|
if (Multihash) {
|
||||||
/* multihash: always insert
|
/* multihash: always insert
|
||||||
* gotta make sure that equal keys always come after
|
* gotta make sure that equal keys always come after
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ostd/platform.hh"
|
#include "ostd/platform.hh"
|
||||||
#include "ostd/string.hh"
|
#include "ostd/string.hh"
|
||||||
#include "ostd/stream.hh"
|
#include "ostd/stream.hh"
|
||||||
|
@ -196,7 +198,7 @@ inline void writef(ConstCharRange fmt, A const &...args) {
|
||||||
fwrite(buf, 1, need, stdout);
|
fwrite(buf, 1, need, stdout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vector<char> s;
|
std::vector<char> s;
|
||||||
s.reserve(need);
|
s.reserve(need);
|
||||||
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
|
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
|
||||||
fwrite(s.data(), 1, need, stdout);
|
fwrite(s.data(), 1, need, stdout);
|
||||||
|
|
|
@ -87,8 +87,8 @@ namespace detail {
|
||||||
|
|
||||||
KeysetImpl(KeysetImpl const &m, A const &alloc): Base(m, alloc) {}
|
KeysetImpl(KeysetImpl const &m, A const &alloc): Base(m, alloc) {}
|
||||||
|
|
||||||
KeysetImpl(KeysetImpl &&m): Base(move(m)) {}
|
KeysetImpl(KeysetImpl &&m): Base(std::move(m)) {}
|
||||||
KeysetImpl(KeysetImpl &&m, A const &alloc): Base(move(m), alloc) {}
|
KeysetImpl(KeysetImpl &&m, A const &alloc): Base(std::move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||||
|
@ -138,7 +138,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeysetImpl &operator=(KeysetImpl &&m) {
|
KeysetImpl &operator=(KeysetImpl &&m) {
|
||||||
Base::operator=(move(m));
|
Base::operator=(std::move(m));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
T &operator[](Key &&key) {
|
T &operator[](Key &&key) {
|
||||||
static_assert(!IsMultihash, "operator[] only allowed on regular keysets");
|
static_assert(!IsMultihash, "operator[] only allowed on regular keysets");
|
||||||
return Base::access_or_insert(move(key));
|
return Base::access_or_insert(std::move(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(KeysetImpl &v) {
|
void swap(KeysetImpl &v) {
|
||||||
|
|
10
ostd/map.hh
10
ostd/map.hh
|
@ -29,7 +29,7 @@ namespace detail {
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static inline void set_key(Element &e, U &&key, A &alloc) {
|
static inline void set_key(Element &e, U &&key, A &alloc) {
|
||||||
allocator_destroy(alloc, &e);
|
allocator_destroy(alloc, &e);
|
||||||
allocator_construct(alloc, &e, forward<U>(key), move(T()));
|
allocator_construct(alloc, &e, std::forward<U>(key), std::move(T()));
|
||||||
}
|
}
|
||||||
static inline void swap_elem(Element &a, Element &b) {
|
static inline void swap_elem(Element &a, Element &b) {
|
||||||
swap_adl(const_cast<K &>(a.first), const_cast<K &>(b.first));
|
swap_adl(const_cast<K &>(a.first), const_cast<K &>(b.first));
|
||||||
|
@ -89,8 +89,8 @@ namespace detail {
|
||||||
|
|
||||||
MapImpl(MapImpl const &m, A const &alloc): Base(m, alloc) {}
|
MapImpl(MapImpl const &m, A const &alloc): Base(m, alloc) {}
|
||||||
|
|
||||||
MapImpl(MapImpl &&m): Base(move(m)) {}
|
MapImpl(MapImpl &&m): Base(std::move(m)) {}
|
||||||
MapImpl(MapImpl &&m, A const &alloc): Base(move(m), alloc) {}
|
MapImpl(MapImpl &&m, A const &alloc): Base(std::move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||||
|
@ -140,7 +140,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
MapImpl &operator=(MapImpl &&m) {
|
MapImpl &operator=(MapImpl &&m) {
|
||||||
Base::operator=(move(m));
|
Base::operator=(std::move(m));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
T &operator[](K &&key) {
|
T &operator[](K &&key) {
|
||||||
static_assert(!IsMultihash, "operator[] only allowed on regular maps");
|
static_assert(!IsMultihash, "operator[] only allowed on regular maps");
|
||||||
return Base::access_or_insert(move(key));
|
return Base::access_or_insert(std::move(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(MapImpl &v) {
|
void swap(MapImpl &v) {
|
||||||
|
|
|
@ -44,16 +44,16 @@ namespace detail {
|
||||||
|
|
||||||
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
|
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
|
||||||
if (p_engaged) {
|
if (p_engaged) {
|
||||||
::new(address_of(p_value)) Value(move(v.p_value));
|
::new(address_of(p_value)) Value(std::move(v.p_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {}
|
constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {}
|
||||||
constexpr MaybeStorage(Value &&v): p_value(move(v)), p_engaged(true) {}
|
constexpr MaybeStorage(Value &&v): p_value(std::move(v)), p_engaged(true) {}
|
||||||
|
|
||||||
template<typename ...A>
|
template<typename ...A>
|
||||||
constexpr MaybeStorage(InPlace, A &&...args):
|
constexpr MaybeStorage(InPlace, A &&...args):
|
||||||
p_value(forward<A>(args)...), p_engaged(true)
|
p_value(std::forward<A>(args)...), p_engaged(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~MaybeStorage() {
|
~MaybeStorage() {
|
||||||
|
@ -83,16 +83,16 @@ namespace detail {
|
||||||
|
|
||||||
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
|
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
|
||||||
if (p_engaged) {
|
if (p_engaged) {
|
||||||
::new(address_of(p_value)) Value(move(v.p_value));
|
::new(address_of(p_value)) Value(std::move(v.p_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {}
|
constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {}
|
||||||
constexpr MaybeStorage(Value &&v): p_value(move(v)), p_engaged(true) {}
|
constexpr MaybeStorage(Value &&v): p_value(std::move(v)), p_engaged(true) {}
|
||||||
|
|
||||||
template<typename ...A>
|
template<typename ...A>
|
||||||
constexpr MaybeStorage(InPlace, A &&...args):
|
constexpr MaybeStorage(InPlace, A &&...args):
|
||||||
p_value(forward<A>(args)...), p_engaged(true)
|
p_value(std::forward<A>(args)...), p_engaged(true)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -129,18 +129,18 @@ public:
|
||||||
Maybe(Maybe &&) = default;
|
Maybe(Maybe &&) = default;
|
||||||
constexpr Maybe(Nothing) {}
|
constexpr Maybe(Nothing) {}
|
||||||
constexpr Maybe(Value const &v): Base(v) {}
|
constexpr Maybe(Value const &v): Base(v) {}
|
||||||
constexpr Maybe(Value &&v): Base(move(v)) {}
|
constexpr Maybe(Value &&v): Base(std::move(v)) {}
|
||||||
|
|
||||||
template<typename ...A, typename = EnableIf<IsConstructible<T, A...>>>
|
template<typename ...A, typename = EnableIf<IsConstructible<T, A...>>>
|
||||||
constexpr explicit Maybe(InPlace, A &&...args):
|
constexpr explicit Maybe(InPlace, A &&...args):
|
||||||
Base(in_place, forward<A>(args)...)
|
Base(in_place, std::forward<A>(args)...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename U, typename ...A, typename = EnableIf<
|
template<typename U, typename ...A, typename = EnableIf<
|
||||||
IsConstructible<T, std::initializer_list<U> &, A...>>
|
IsConstructible<T, std::initializer_list<U> &, A...>>
|
||||||
>
|
>
|
||||||
constexpr explicit Maybe(InPlace, std::initializer_list<U> il, A &&...args):
|
constexpr explicit Maybe(InPlace, std::initializer_list<U> il, A &&...args):
|
||||||
Base(in_place, il, forward<A>(args)...)
|
Base(in_place, il, std::forward<A>(args)...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~Maybe() = default;
|
~Maybe() = default;
|
||||||
|
@ -172,13 +172,13 @@ public:
|
||||||
Maybe &operator=(Maybe &&v) {
|
Maybe &operator=(Maybe &&v) {
|
||||||
if (this->p_engaged == v.p_engaged) {
|
if (this->p_engaged == v.p_engaged) {
|
||||||
if (this->p_engaged) {
|
if (this->p_engaged) {
|
||||||
this->p_value = move(v.p_value);
|
this->p_value = std::move(v.p_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this->p_engaged) {
|
if (this->p_engaged) {
|
||||||
this->p_value.~Value();
|
this->p_value.~Value();
|
||||||
} else {
|
} else {
|
||||||
::new(address_of(this->p_value)) Value(move(v.p_value));
|
::new(address_of(this->p_value)) Value(std::move(v.p_value));
|
||||||
}
|
}
|
||||||
this->p_engaged = v.p_engaged;
|
this->p_engaged = v.p_engaged;
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,9 @@ public:
|
||||||
>>
|
>>
|
||||||
Maybe &operator=(U &&v) {
|
Maybe &operator=(U &&v) {
|
||||||
if (this->p_engaged) {
|
if (this->p_engaged) {
|
||||||
this->p_value = forward<U>(v);
|
this->p_value = std::forward<U>(v);
|
||||||
} else {
|
} else {
|
||||||
::new(address_of(this->p_value)) Value(forward<U>(v));
|
::new(address_of(this->p_value)) Value(std::forward<U>(v));
|
||||||
this->p_engaged = true;
|
this->p_engaged = true;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -202,7 +202,7 @@ public:
|
||||||
template<typename ...A, typename = EnableIf<IsConstructible<Value, A...>>>
|
template<typename ...A, typename = EnableIf<IsConstructible<Value, A...>>>
|
||||||
void emplace(A &&...args) {
|
void emplace(A &&...args) {
|
||||||
*this = nothing;
|
*this = nothing;
|
||||||
::new(address_of(this->p_value)) Value(forward<A>(args)...);
|
::new(address_of(this->p_value)) Value(std::forward<A>(args)...);
|
||||||
this->p_engaged = true;
|
this->p_engaged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ public:
|
||||||
void emplace(std::initializer_list<U> il, A &&...args) {
|
void emplace(std::initializer_list<U> il, A &&...args) {
|
||||||
*this = nothing;
|
*this = nothing;
|
||||||
::new(address_of(this->p_value))
|
::new(address_of(this->p_value))
|
||||||
Value(il, forward<A>(args)...);
|
Value(il, std::forward<A>(args)...);
|
||||||
this->p_engaged = true;
|
this->p_engaged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,11 +233,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Value const &&operator*() const && {
|
constexpr Value const &&operator*() const && {
|
||||||
return ostd::move(this->p_value);
|
return std::move(this->p_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Value &&operator*() && {
|
constexpr Value &&operator*() && {
|
||||||
return ostd::move(this->p_value);
|
return std::move(this->p_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr explicit operator bool() const { return this->p_engaged; }
|
constexpr explicit operator bool() const { return this->p_engaged; }
|
||||||
|
@ -251,11 +251,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Value const &&value() const && {
|
constexpr Value const &&value() const && {
|
||||||
return ostd::move(this->p_value);
|
return std::move(this->p_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Value &&value() && {
|
constexpr Value &&value() && {
|
||||||
return ostd::move(this->p_value);
|
return std::move(this->p_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
|
@ -268,7 +268,7 @@ public:
|
||||||
IsConvertible<U, Value>,
|
IsConvertible<U, Value>,
|
||||||
"Maybe<T>::value_or: U must be convertible to T"
|
"Maybe<T>::value_or: U must be convertible to T"
|
||||||
);
|
);
|
||||||
return this->p_engaged ? this->p_value : Value(forward<U>(v));
|
return this->p_engaged ? this->p_value : Value(std::forward<U>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
|
@ -281,7 +281,7 @@ public:
|
||||||
IsConvertible<U, Value>,
|
IsConvertible<U, Value>,
|
||||||
"Maybe<T>::value_or: U must be convertible to T"
|
"Maybe<T>::value_or: U must be convertible to T"
|
||||||
);
|
);
|
||||||
return this->p_engaged ? move(this->p_value) : Value(forward<U>(v));
|
return this->p_engaged ? std::move(this->p_value) : Value(std::forward<U>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Maybe &v) {
|
void swap(Maybe &v) {
|
||||||
|
@ -291,10 +291,10 @@ public:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this->p_engaged) {
|
if (this->p_engaged) {
|
||||||
::new(address_of(v.p_value)) Value(move(this->p_value));
|
::new(address_of(v.p_value)) Value(std::move(this->p_value));
|
||||||
this->p_value.~Value();
|
this->p_value.~Value();
|
||||||
} else {
|
} else {
|
||||||
::new(address_of(this->p_value)) Value(move(v.p_value));
|
::new(address_of(this->p_value)) Value(std::move(v.p_value));
|
||||||
v.p_value.~Value();
|
v.p_value.~Value();
|
||||||
}
|
}
|
||||||
detail::swap_adl(this->p_engaged, v.p_engaged);
|
detail::swap_adl(this->p_engaged, v.p_engaged);
|
||||||
|
@ -466,17 +466,17 @@ inline constexpr bool operator>=(T const &b, Maybe<T> const &a) {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr Maybe<Decay<T>> make_maybe(T &&v) {
|
inline constexpr Maybe<Decay<T>> make_maybe(T &&v) {
|
||||||
return Maybe<Decay<T>>(forward<T>(v));
|
return Maybe<Decay<T>>(std::forward<T>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
inline constexpr Maybe<T> make_maybe(A &&...args) {
|
inline constexpr Maybe<T> make_maybe(A &&...args) {
|
||||||
return Maybe<T>(in_place, forward<A>(args)...);
|
return Maybe<T>(in_place, std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U, typename ...A>
|
template<typename T, typename U, typename ...A>
|
||||||
inline constexpr Maybe<T> make_maybe(std::initializer_list<U> il, A &&...args) {
|
inline constexpr Maybe<T> make_maybe(std::initializer_list<U> il, A &&...args) {
|
||||||
return Maybe<T>(in_place, il, forward<A>(args)...);
|
return Maybe<T>(in_place, il, std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
|
@ -275,12 +275,14 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Box(Pointer p, RemoveReference<D> &&d) noexcept:
|
Box(Pointer p, RemoveReference<D> &&d) noexcept:
|
||||||
p_stor(p, move(d))
|
p_stor(p, std::move(d))
|
||||||
{
|
{
|
||||||
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u) noexcept: p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u) noexcept:
|
||||||
|
p_stor(u.release(), std::forward<D>(u.get_deleter()))
|
||||||
|
{}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(
|
Box(
|
||||||
|
@ -290,11 +292,11 @@ public:
|
||||||
IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>),
|
IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>),
|
||||||
Nat
|
Nat
|
||||||
> = Nat()
|
> = Nat()
|
||||||
) noexcept: p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
) noexcept: p_stor(u.release(), std::forward<DD>(u.get_deleter())) {}
|
||||||
|
|
||||||
Box &operator=(Box &&u) noexcept {
|
Box &operator=(Box &&u) noexcept {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.second() = forward<D>(u.get_deleter());
|
p_stor.second() = std::forward<D>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +308,7 @@ public:
|
||||||
Box &
|
Box &
|
||||||
> operator=(Box<TT, DD> &&u) noexcept {
|
> operator=(Box<TT, DD> &&u) noexcept {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.second() = forward<DD>(u.get_deleter());
|
p_stor.second() = std::forward<DD>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,18 +414,20 @@ public:
|
||||||
|
|
||||||
template<typename U> Box(U p, RemoveReference<D> &&d,
|
template<typename U> Box(U p, RemoveReference<D> &&d,
|
||||||
EnableIf<detail::SameOrLessCvQualified<U, Pointer>, Nat> = Nat()) noexcept:
|
EnableIf<detail::SameOrLessCvQualified<U, Pointer>, Nat> = Nat()) noexcept:
|
||||||
p_stor(p, move(d))
|
p_stor(p, std::move(d))
|
||||||
{
|
{
|
||||||
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Nullptr, RemoveReference<D> &&d) noexcept:
|
Box(Nullptr, RemoveReference<D> &&d) noexcept:
|
||||||
p_stor(nullptr, move(d))
|
p_stor(nullptr, std::move(d))
|
||||||
{
|
{
|
||||||
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u) noexcept: p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u) noexcept:
|
||||||
|
p_stor(u.release(), std::forward<D>(u.get_deleter()))
|
||||||
|
{}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(
|
Box(
|
||||||
|
@ -434,12 +438,12 @@ public:
|
||||||
Nat
|
Nat
|
||||||
> = Nat()
|
> = Nat()
|
||||||
) noexcept:
|
) noexcept:
|
||||||
p_stor(u.release(), forward<DD>(u.get_deleter()))
|
p_stor(u.release(), std::forward<DD>(u.get_deleter()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Box &operator=(Box &&u) noexcept {
|
Box &operator=(Box &&u) noexcept {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.second() = forward<D>(u.get_deleter());
|
p_stor.second() = std::forward<D>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +455,7 @@ public:
|
||||||
Box &
|
Box &
|
||||||
> operator=(Box<TT, DD> &&u) noexcept {
|
> operator=(Box<TT, DD> &&u) noexcept {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.second() = forward<DD>(u.get_deleter());
|
p_stor.second() = std::forward<DD>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +535,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
typename detail::BoxIf<T>::BoxType make_box(A &&...args) {
|
typename detail::BoxIf<T>::BoxType make_box(A &&...args) {
|
||||||
return Box<T>(new T(forward<A>(args)...));
|
return Box<T>(new T(std::forward<A>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -904,7 +908,7 @@ inline void allocator_deallocate(
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename A, typename T, typename ...Args>
|
template<typename A, typename T, typename ...Args>
|
||||||
auto construct_test(A &&a, T *p, Args &&...args) ->
|
auto construct_test(A &&a, T *p, Args &&...args) ->
|
||||||
decltype(a.construct(p, forward<Args>(args)...), True());
|
decltype(a.construct(p, std::forward<Args>(args)...), True());
|
||||||
|
|
||||||
template<typename A, typename T, typename ...Args>
|
template<typename A, typename T, typename ...Args>
|
||||||
auto construct_test(A const &, T *, Args &&...) -> False;
|
auto construct_test(A const &, T *, Args &&...) -> False;
|
||||||
|
@ -919,12 +923,12 @@ namespace detail {
|
||||||
|
|
||||||
template<typename A, typename T, typename ...Args>
|
template<typename A, typename T, typename ...Args>
|
||||||
inline void construct(True, A &a, T *p, Args &&...args) {
|
inline void construct(True, A &a, T *p, Args &&...args) {
|
||||||
a.construct(p, forward<Args>(args)...);
|
a.construct(p, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename T, typename ...Args>
|
template<typename A, typename T, typename ...Args>
|
||||||
inline void construct(False, A &, T *p, Args &&...args) {
|
inline void construct(False, A &, T *p, Args &&...args) {
|
||||||
::new (p) T(forward<Args>(args)...);
|
::new (p) T(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
|
@ -932,7 +936,7 @@ template<typename A, typename T, typename ...Args>
|
||||||
inline void allocator_construct(A &a, T *p, Args &&...args) {
|
inline void allocator_construct(A &a, T *p, Args &&...args) {
|
||||||
detail::construct(
|
detail::construct(
|
||||||
BoolConstant<detail::ConstructTest<A, T *, Args...>>(),
|
BoolConstant<detail::ConstructTest<A, T *, Args...>>(),
|
||||||
a, p, forward<Args>(args)...
|
a, p, std::forward<Args>(args)...
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
120
ostd/range.hh
120
ostd/range.hh
|
@ -224,13 +224,13 @@ namespace detail {
|
||||||
::new(&get_ref()) T(range);
|
::new(&get_ref()) T(range);
|
||||||
}
|
}
|
||||||
explicit RangeIterator(T &&range): p_range(), p_init(true) {
|
explicit RangeIterator(T &&range): p_range(), p_init(true) {
|
||||||
::new(&get_ref()) T(move(range));
|
::new(&get_ref()) T(std::move(range));
|
||||||
}
|
}
|
||||||
RangeIterator(const RangeIterator &v): p_range(), p_init(true) {
|
RangeIterator(const RangeIterator &v): p_range(), p_init(true) {
|
||||||
::new(&get_ref()) T(v.get_ref());
|
::new(&get_ref()) T(v.get_ref());
|
||||||
}
|
}
|
||||||
RangeIterator(RangeIterator &&v): p_range(), p_init(true) {
|
RangeIterator(RangeIterator &&v): p_range(), p_init(true) {
|
||||||
::new(&get_ref()) T(move(v.get_ref()));
|
::new(&get_ref()) T(std::move(v.get_ref()));
|
||||||
}
|
}
|
||||||
RangeIterator &operator=(const RangeIterator &v) {
|
RangeIterator &operator=(const RangeIterator &v) {
|
||||||
destroy();
|
destroy();
|
||||||
|
@ -332,7 +332,7 @@ public:
|
||||||
RangeHalf(RangeHalf<U> const &half): p_range(half.p_range) {}
|
RangeHalf(RangeHalf<U> const &half): p_range(half.p_range) {}
|
||||||
|
|
||||||
RangeHalf(RangeHalf const &half): p_range(half.p_range) {}
|
RangeHalf(RangeHalf const &half): p_range(half.p_range) {}
|
||||||
RangeHalf(RangeHalf &&half): p_range(move(half.p_range)) {}
|
RangeHalf(RangeHalf &&half): p_range(std::move(half.p_range)) {}
|
||||||
|
|
||||||
RangeHalf &operator=(RangeHalf const &half) {
|
RangeHalf &operator=(RangeHalf const &half) {
|
||||||
p_range = half.p_range;
|
p_range = half.p_range;
|
||||||
|
@ -340,7 +340,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeHalf &operator=(RangeHalf &&half) {
|
RangeHalf &operator=(RangeHalf &&half) {
|
||||||
p_range = move(half.p_range);
|
p_range = std::move(half.p_range);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,12 +562,12 @@ struct InputRange {
|
||||||
|
|
||||||
template<typename R1, typename ...RR>
|
template<typename R1, typename ...RR>
|
||||||
JoinRange<B, R1, RR...> join(R1 r1, RR ...rr) const {
|
JoinRange<B, R1, RR...> join(R1 r1, RR ...rr) const {
|
||||||
return JoinRange<B, R1, RR...>(iter(), move(r1), move(rr)...);
|
return JoinRange<B, R1, RR...>(iter(), std::move(r1), std::move(rr)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename ...RR>
|
template<typename R1, typename ...RR>
|
||||||
ZipRange<B, R1, RR...> zip(R1 r1, RR ...rr) const {
|
ZipRange<B, R1, RR...> zip(R1 r1, RR ...rr) const {
|
||||||
return ZipRange<B, R1, RR...>(iter(), move(r1), move(rr)...);
|
return ZipRange<B, R1, RR...>(iter(), std::move(r1), std::move(rr)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeHalf<B> half() const {
|
RangeHalf<B> half() const {
|
||||||
|
@ -660,7 +660,7 @@ struct InputRange {
|
||||||
|
|
||||||
template<typename R, typename F, typename = EnableIf<IsInputRange<R>>>
|
template<typename R, typename F, typename = EnableIf<IsInputRange<R>>>
|
||||||
inline auto operator|(R &&range, F &&func) {
|
inline auto operator|(R &&range, F &&func) {
|
||||||
return func(forward<R>(range));
|
return func(std::forward<R>(range));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto reverse() {
|
inline auto reverse() {
|
||||||
|
@ -688,51 +688,55 @@ inline auto chunks(T n) {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename ...R, Size ...I>
|
template<typename T, typename ...R, Size ...I>
|
||||||
inline auto join_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
|
inline auto join_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
|
||||||
return obj.join(forward<R>(get<I>(forward<Tuple<R &&...>>(tup)))...);
|
return obj.join(std::forward<R>(
|
||||||
|
get<I>(std::forward<Tuple<R &&...>>(tup))
|
||||||
|
)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename ...R, Size ...I>
|
template<typename T, typename ...R, Size ...I>
|
||||||
inline auto zip_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
|
inline auto zip_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
|
||||||
return obj.zip(forward<R>(get<I>(forward<Tuple<R &&...>>(tup)))...);
|
return obj.zip(std::forward<R>(
|
||||||
|
get<I>(std::forward<Tuple<R &&...>>(tup))
|
||||||
|
)...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto join(R &&range) {
|
inline auto join(R &&range) {
|
||||||
return [range = forward<R>(range)](auto &&obj) mutable {
|
return [range = std::forward<R>(range)](auto &&obj) mutable {
|
||||||
return obj.join(forward<R>(range));
|
return obj.join(std::forward<R>(range));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename ...R>
|
template<typename R1, typename ...R>
|
||||||
inline auto join(R1 &&r1, R &&...rr) {
|
inline auto join(R1 &&r1, R &&...rr) {
|
||||||
return [
|
return [
|
||||||
ranges = forward_as_tuple(forward<R1>(r1), forward<R>(rr)...)
|
ranges = forward_as_tuple(std::forward<R1>(r1), std::forward<R>(rr)...)
|
||||||
] (auto &&obj) mutable {
|
] (auto &&obj) mutable {
|
||||||
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
|
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
|
||||||
return detail::join_proxy(
|
return detail::join_proxy(
|
||||||
forward<decltype(obj)>(obj),
|
std::forward<decltype(obj)>(obj),
|
||||||
forward<decltype(ranges)>(ranges), Index()
|
std::forward<decltype(ranges)>(ranges), Index()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
inline auto zip(R &&range) {
|
inline auto zip(R &&range) {
|
||||||
return [range = forward<R>(range)](auto &&obj) mutable {
|
return [range = std::forward<R>(range)](auto &&obj) mutable {
|
||||||
return obj.zip(forward<R>(range));
|
return obj.zip(std::forward<R>(range));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename ...R>
|
template<typename R1, typename ...R>
|
||||||
inline auto zip(R1 &&r1, R &&...rr) {
|
inline auto zip(R1 &&r1, R &&...rr) {
|
||||||
return [
|
return [
|
||||||
ranges = forward_as_tuple(forward<R1>(r1), forward<R>(rr)...)
|
ranges = forward_as_tuple(std::forward<R1>(r1), std::forward<R>(rr)...)
|
||||||
] (auto &&obj) mutable {
|
] (auto &&obj) mutable {
|
||||||
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
|
using Index = detail::MakeTupleIndices<sizeof...(R) + 1>;
|
||||||
return detail::zip_proxy(
|
return detail::zip_proxy(
|
||||||
forward<decltype(obj)>(obj),
|
std::forward<decltype(obj)>(obj),
|
||||||
forward<decltype(ranges)>(ranges), Index()
|
std::forward<decltype(ranges)>(ranges), Index()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -789,13 +793,13 @@ public:
|
||||||
p_beg(range.p_beg), p_end(range.p_end)
|
p_beg(range.p_beg), p_end(range.p_end)
|
||||||
{}
|
{}
|
||||||
HalfRange(HalfRange &&range):
|
HalfRange(HalfRange &&range):
|
||||||
p_beg(move(range.p_beg)), p_end(move(range.p_end))
|
p_beg(std::move(range.p_beg)), p_end(std::move(range.p_end))
|
||||||
{}
|
{}
|
||||||
HalfRange(T const &beg, T const &end):
|
HalfRange(T const &beg, T const &end):
|
||||||
p_beg(beg),p_end(end)
|
p_beg(beg),p_end(end)
|
||||||
{}
|
{}
|
||||||
HalfRange(T &&beg, T &&end):
|
HalfRange(T &&beg, T &&end):
|
||||||
p_beg(move(beg)), p_end(move(end))
|
p_beg(std::move(beg)), p_end(std::move(end))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
HalfRange &operator=(HalfRange const &range) {
|
HalfRange &operator=(HalfRange const &range) {
|
||||||
|
@ -805,8 +809,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
HalfRange &operator=(HalfRange &&range) {
|
HalfRange &operator=(HalfRange &&range) {
|
||||||
p_beg = move(range.p_beg);
|
p_beg = std::move(range.p_beg);
|
||||||
p_end = move(range.p_end);
|
p_end = std::move(range.p_end);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,7 +866,7 @@ public:
|
||||||
return p_beg.range().put(v);
|
return p_beg.range().put(v);
|
||||||
}
|
}
|
||||||
bool put(RangeValue<Rtype> &&v) {
|
bool put(RangeValue<Rtype> &&v) {
|
||||||
return p_beg.range().put(move(v));
|
return p_beg.range().put(std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeValue<Rtype> *data() { return p_beg.data(); }
|
RangeValue<Rtype> *data() { return p_beg.data(); }
|
||||||
|
@ -884,14 +888,14 @@ public:
|
||||||
ReverseRange() = delete;
|
ReverseRange() = delete;
|
||||||
ReverseRange(T const &range): p_range(range) {}
|
ReverseRange(T const &range): p_range(range) {}
|
||||||
ReverseRange(ReverseRange const &it): p_range(it.p_range) {}
|
ReverseRange(ReverseRange const &it): p_range(it.p_range) {}
|
||||||
ReverseRange(ReverseRange &&it): p_range(move(it.p_range)) {}
|
ReverseRange(ReverseRange &&it): p_range(std::move(it.p_range)) {}
|
||||||
|
|
||||||
ReverseRange &operator=(ReverseRange const &v) {
|
ReverseRange &operator=(ReverseRange const &v) {
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(ReverseRange &&v) {
|
ReverseRange &operator=(ReverseRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(T const &v) {
|
ReverseRange &operator=(T const &v) {
|
||||||
|
@ -899,7 +903,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(T &&v) {
|
ReverseRange &operator=(T &&v) {
|
||||||
p_range = move(v);
|
p_range = std::move(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,14 +963,14 @@ public:
|
||||||
MoveRange() = delete;
|
MoveRange() = delete;
|
||||||
MoveRange(T const &range): p_range(range) {}
|
MoveRange(T const &range): p_range(range) {}
|
||||||
MoveRange(MoveRange const &it): p_range(it.p_range) {}
|
MoveRange(MoveRange const &it): p_range(it.p_range) {}
|
||||||
MoveRange(MoveRange &&it): p_range(move(it.p_range)) {}
|
MoveRange(MoveRange &&it): p_range(std::move(it.p_range)) {}
|
||||||
|
|
||||||
MoveRange &operator=(MoveRange const &v) {
|
MoveRange &operator=(MoveRange const &v) {
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(MoveRange &&v) {
|
MoveRange &operator=(MoveRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(T const &v) {
|
MoveRange &operator=(T const &v) {
|
||||||
|
@ -974,7 +978,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(T &&v) {
|
MoveRange &operator=(T &&v) {
|
||||||
p_range = move(v);
|
p_range = std::move(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,17 +1011,17 @@ public:
|
||||||
Rsize push_front_n(Rsize n) { return p_range.push_front_n(n); }
|
Rsize push_front_n(Rsize n) { return p_range.push_front_n(n); }
|
||||||
Rsize push_back_n(Rsize n) { return p_range.push_back_n(n); }
|
Rsize push_back_n(Rsize n) { return p_range.push_back_n(n); }
|
||||||
|
|
||||||
Rref front() const { return move(p_range.front()); }
|
Rref front() const { return std::move(p_range.front()); }
|
||||||
Rref back() const { return move(p_range.back()); }
|
Rref back() const { return std::move(p_range.back()); }
|
||||||
|
|
||||||
Rref operator[](Rsize i) const { return move(p_range[i]); }
|
Rref operator[](Rsize i) const { return std::move(p_range[i]); }
|
||||||
|
|
||||||
MoveRange<T> slice(Rsize start, Rsize end) const {
|
MoveRange<T> slice(Rsize start, Rsize end) const {
|
||||||
return MoveRange<T>(p_range.slice(start, end));
|
return MoveRange<T>(p_range.slice(start, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool put(Rval const &v) { return p_range.put(v); }
|
bool put(Rval const &v) { return p_range.put(v); }
|
||||||
bool put(Rval &&v) { return p_range.put(move(v)); }
|
bool put(Rval &&v) { return p_range.put(std::move(v)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1170,7 +1174,7 @@ public:
|
||||||
if (empty()) {
|
if (empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*(p_beg++) = move(v);
|
*(p_beg++) = std::move(v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1228,6 +1232,11 @@ inline PointerRange<T const> iter(T const (&array)[N]) {
|
||||||
return PointerRange<T const>(array, N);
|
return PointerRange<T const>(array, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, Size N>
|
||||||
|
inline PointerRange<T const> citer(T const (&array)[N]) {
|
||||||
|
return PointerRange<T const>(array, N);
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
struct PtrNat {};
|
struct PtrNat {};
|
||||||
}
|
}
|
||||||
|
@ -1273,7 +1282,7 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EnumeratedRange(EnumeratedRange &&it):
|
EnumeratedRange(EnumeratedRange &&it):
|
||||||
p_range(move(it.p_range)), p_index(it.p_index)
|
p_range(std::move(it.p_range)), p_index(it.p_index)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EnumeratedRange &operator=(EnumeratedRange const &v) {
|
EnumeratedRange &operator=(EnumeratedRange const &v) {
|
||||||
|
@ -1282,7 +1291,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EnumeratedRange &operator=(EnumeratedRange &&v) {
|
EnumeratedRange &operator=(EnumeratedRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
p_index = v.p_index;
|
p_index = v.p_index;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1292,7 +1301,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EnumeratedRange &operator=(T &&v) {
|
EnumeratedRange &operator=(T &&v) {
|
||||||
p_range = move(v);
|
p_range = std::move(v);
|
||||||
p_index = 0;
|
p_index = 0;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1339,14 +1348,14 @@ public:
|
||||||
p_range(it.p_range), p_remaining(it.p_remaining)
|
p_range(it.p_range), p_remaining(it.p_remaining)
|
||||||
{}
|
{}
|
||||||
TakeRange(TakeRange &&it):
|
TakeRange(TakeRange &&it):
|
||||||
p_range(move(it.p_range)), p_remaining(it.p_remaining)
|
p_range(std::move(it.p_range)), p_remaining(it.p_remaining)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TakeRange &operator=(TakeRange const &v) {
|
TakeRange &operator=(TakeRange const &v) {
|
||||||
p_range = v.p_range; p_remaining = v.p_remaining; return *this;
|
p_range = v.p_range; p_remaining = v.p_remaining; return *this;
|
||||||
}
|
}
|
||||||
TakeRange &operator=(TakeRange &&v) {
|
TakeRange &operator=(TakeRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
p_remaining = v.p_remaining;
|
p_remaining = v.p_remaining;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1391,14 +1400,14 @@ public:
|
||||||
p_range(it.p_range), p_chunksize(it.p_chunksize)
|
p_range(it.p_range), p_chunksize(it.p_chunksize)
|
||||||
{}
|
{}
|
||||||
ChunksRange(ChunksRange &&it):
|
ChunksRange(ChunksRange &&it):
|
||||||
p_range(move(it.p_range)), p_chunksize(it.p_chunksize)
|
p_range(std::move(it.p_range)), p_chunksize(it.p_chunksize)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ChunksRange &operator=(ChunksRange const &v) {
|
ChunksRange &operator=(ChunksRange const &v) {
|
||||||
p_range = v.p_range; p_chunksize = v.p_chunksize; return *this;
|
p_range = v.p_range; p_chunksize = v.p_chunksize; return *this;
|
||||||
}
|
}
|
||||||
ChunksRange &operator=(ChunksRange &&v) {
|
ChunksRange &operator=(ChunksRange &&v) {
|
||||||
p_range = move(v.p_range);
|
p_range = std::move(v.p_range);
|
||||||
p_chunksize = v.p_chunksize;
|
p_chunksize = v.p_chunksize;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1505,9 +1514,9 @@ private:
|
||||||
public:
|
public:
|
||||||
JoinRange() = delete;
|
JoinRange() = delete;
|
||||||
JoinRange(R const &...ranges): p_ranges(ranges...) {}
|
JoinRange(R const &...ranges): p_ranges(ranges...) {}
|
||||||
JoinRange(R &&...ranges): p_ranges(forward<R>(ranges)...) {}
|
JoinRange(R &&...ranges): p_ranges(std::forward<R>(ranges)...) {}
|
||||||
JoinRange(JoinRange const &v): p_ranges(v.p_ranges) {}
|
JoinRange(JoinRange const &v): p_ranges(v.p_ranges) {}
|
||||||
JoinRange(JoinRange &&v): p_ranges(move(v.p_ranges)) {}
|
JoinRange(JoinRange &&v): p_ranges(std::move(v.p_ranges)) {}
|
||||||
|
|
||||||
JoinRange &operator=(JoinRange const &v) {
|
JoinRange &operator=(JoinRange const &v) {
|
||||||
p_ranges = v.p_ranges;
|
p_ranges = v.p_ranges;
|
||||||
|
@ -1515,7 +1524,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinRange &operator=(JoinRange &&v) {
|
JoinRange &operator=(JoinRange &&v) {
|
||||||
p_ranges = move(v.p_ranges);
|
p_ranges = std::move(v.p_ranges);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1617,9 +1626,9 @@ private:
|
||||||
public:
|
public:
|
||||||
ZipRange() = delete;
|
ZipRange() = delete;
|
||||||
ZipRange(R const &...ranges): p_ranges(ranges...) {}
|
ZipRange(R const &...ranges): p_ranges(ranges...) {}
|
||||||
ZipRange(R &&...ranges): p_ranges(forward<R>(ranges)...) {}
|
ZipRange(R &&...ranges): p_ranges(std::forward<R>(ranges)...) {}
|
||||||
ZipRange(ZipRange const &v): p_ranges(v.p_ranges) {}
|
ZipRange(ZipRange const &v): p_ranges(v.p_ranges) {}
|
||||||
ZipRange(ZipRange &&v): p_ranges(move(v.p_ranges)) {}
|
ZipRange(ZipRange &&v): p_ranges(std::move(v.p_ranges)) {}
|
||||||
|
|
||||||
ZipRange &operator=(ZipRange const &v) {
|
ZipRange &operator=(ZipRange const &v) {
|
||||||
p_ranges = v.p_ranges;
|
p_ranges = v.p_ranges;
|
||||||
|
@ -1627,7 +1636,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipRange &operator=(ZipRange &&v) {
|
ZipRange &operator=(ZipRange &&v) {
|
||||||
p_ranges = move(v.p_ranges);
|
p_ranges = std::move(v.p_ranges);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1655,9 +1664,9 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
|
||||||
typename T::Reference, typename T::Size, typename T::Difference> {
|
typename T::Reference, typename T::Size, typename T::Difference> {
|
||||||
AppenderRange(): p_data() {}
|
AppenderRange(): p_data() {}
|
||||||
AppenderRange(T const &v): p_data(v) {}
|
AppenderRange(T const &v): p_data(v) {}
|
||||||
AppenderRange(T &&v): p_data(move(v)) {}
|
AppenderRange(T &&v): p_data(std::move(v)) {}
|
||||||
AppenderRange(AppenderRange const &v): p_data(v.p_data) {}
|
AppenderRange(AppenderRange const &v): p_data(v.p_data) {}
|
||||||
AppenderRange(AppenderRange &&v): p_data(move(v.p_data)) {}
|
AppenderRange(AppenderRange &&v): p_data(std::move(v.p_data)) {}
|
||||||
|
|
||||||
AppenderRange &operator=(AppenderRange const &v) {
|
AppenderRange &operator=(AppenderRange const &v) {
|
||||||
p_data = v.p_data;
|
p_data = v.p_data;
|
||||||
|
@ -1665,7 +1674,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
AppenderRange &operator=(AppenderRange &&v) {
|
AppenderRange &operator=(AppenderRange &&v) {
|
||||||
p_data = move(v.p_data);
|
p_data = std::move(v.p_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1675,7 +1684,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
AppenderRange &operator=(T &&v) {
|
AppenderRange &operator=(T &&v) {
|
||||||
p_data = move(v);
|
p_data = std::move(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1693,7 +1702,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool put(typename T::Value &&v) {
|
bool put(typename T::Value &&v) {
|
||||||
p_data.push(move(v));
|
p_data.push(std::move(v));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1709,12 +1718,9 @@ inline AppenderRange<T> appender() {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline AppenderRange<T> appender(T &&v) {
|
inline AppenderRange<T> appender(T &&v) {
|
||||||
return AppenderRange<T>(forward<T>(v));
|
return AppenderRange<T>(std::forward<T>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// range of
|
|
||||||
template<typename T> using RangeOf = decltype(iter(declval<T>()));
|
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,8 +78,8 @@ namespace detail {
|
||||||
|
|
||||||
SetImpl(SetImpl const &m, A const &alloc): Base(m, alloc) {}
|
SetImpl(SetImpl const &m, A const &alloc): Base(m, alloc) {}
|
||||||
|
|
||||||
SetImpl(SetImpl &&m): Base(move(m)) {}
|
SetImpl(SetImpl &&m): Base(std::move(m)) {}
|
||||||
SetImpl(SetImpl &&m, A const &alloc): Base(move(m), alloc) {}
|
SetImpl(SetImpl &&m, A const &alloc): Base(std::move(m), alloc) {}
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
template<typename R, typename = EnableIf<
|
||||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
||||||
|
@ -129,7 +129,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
SetImpl &operator=(SetImpl &&m) {
|
SetImpl &operator=(SetImpl &&m) {
|
||||||
Base::operator=(move(m));
|
Base::operator=(std::move(m));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ostd/platform.hh"
|
#include "ostd/platform.hh"
|
||||||
#include "ostd/types.hh"
|
#include "ostd/types.hh"
|
||||||
#include "ostd/range.hh"
|
#include "ostd/range.hh"
|
||||||
|
@ -146,7 +148,7 @@ public:
|
||||||
} else if (Size(need) < sizeof(buf)) {
|
} else if (Size(need) < sizeof(buf)) {
|
||||||
return write_bytes(buf, need) == Size(need);
|
return write_bytes(buf, need) == Size(need);
|
||||||
}
|
}
|
||||||
Vector<char> s;
|
std::vector<char> s;
|
||||||
s.reserve(need);
|
s.reserve(need);
|
||||||
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
|
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
|
||||||
return write_bytes(s.data(), need) == Size(need);
|
return write_bytes(s.data(), need) == Size(need);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "ostd/vector.hh"
|
#include "ostd/vector.hh"
|
||||||
#include "ostd/functional.hh"
|
#include "ostd/functional.hh"
|
||||||
#include "ostd/type_traits.hh"
|
#include "ostd/type_traits.hh"
|
||||||
|
#include "ostd/algorithm.hh"
|
||||||
|
|
||||||
namespace ostd {
|
namespace ostd {
|
||||||
static constexpr Size npos = -1;
|
static constexpr Size npos = -1;
|
||||||
|
@ -342,7 +343,7 @@ public:
|
||||||
}
|
}
|
||||||
StringBase(StringBase &&s):
|
StringBase(StringBase &&s):
|
||||||
p_len(s.p_len), p_cap(s.p_cap),
|
p_len(s.p_len), p_cap(s.p_cap),
|
||||||
p_buf(s.p_buf.first(), move(s.p_buf.second()))
|
p_buf(s.p_buf.first(), std::move(s.p_buf.second()))
|
||||||
{
|
{
|
||||||
s.p_len = s.p_cap = 0;
|
s.p_len = s.p_cap = 0;
|
||||||
s.p_buf.first() = reinterpret_cast<Pointer>(&s.p_len);
|
s.p_buf.first() = reinterpret_cast<Pointer>(&s.p_len);
|
||||||
|
@ -455,7 +456,7 @@ public:
|
||||||
p_len = v.p_len;
|
p_len = v.p_len;
|
||||||
p_cap = v.p_cap;
|
p_cap = v.p_cap;
|
||||||
p_buf.~StrPair();
|
p_buf.~StrPair();
|
||||||
new (&p_buf) StrPair(v.release(), move(v.p_buf.second()));
|
new (&p_buf) StrPair(v.release(), std::move(v.p_buf.second()));
|
||||||
if (!p_cap) {
|
if (!p_cap) {
|
||||||
p_buf.first() = reinterpret_cast<Pointer>(&p_len);
|
p_buf.first() = reinterpret_cast<Pointer>(&p_len);
|
||||||
}
|
}
|
||||||
|
@ -835,7 +836,7 @@ struct ToString<T, EnableIf<
|
||||||
if (!v.to_string(sink)) {
|
if (!v.to_string(sink)) {
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
return move(app.get());
|
return std::move(app.get());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1048,11 +1049,11 @@ inline String operator+(char lhs, String const &rhs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline String operator+(String &&lhs, ConstCharRange rhs) {
|
inline String operator+(String &&lhs, ConstCharRange rhs) {
|
||||||
String ret(move(lhs)); ret += rhs; return ret;
|
String ret(std::move(lhs)); ret += rhs; return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline String operator+(String &&lhs, char rhs) {
|
inline String operator+(String &&lhs, char rhs) {
|
||||||
String ret(move(lhs)); ret += rhs; return ret;
|
String ret(std::move(lhs)); ret += rhs; return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace detail {
|
||||||
template<typename T, typename = EnableIf<
|
template<typename T, typename = EnableIf<
|
||||||
!IsSame<Decay<T>, TupleLeaf> && IsConstructible<H, T>
|
!IsSame<Decay<T>, TupleLeaf> && IsConstructible<H, T>
|
||||||
>>
|
>>
|
||||||
explicit TupleLeaf(T &&t): p_value(forward<T>(t)) {
|
explicit TupleLeaf(T &&t): p_value(std::forward<T>(t)) {
|
||||||
static_assert(
|
static_assert(
|
||||||
!IsReference<H> || (
|
!IsReference<H> || (
|
||||||
IsLvalueReference<H> && (
|
IsLvalueReference<H> && (
|
||||||
|
@ -80,7 +80,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 0>, A const &, T &&t):
|
explicit TupleLeaf(Constant<int, 0>, A const &, T &&t):
|
||||||
p_value(forward<T>(t))
|
p_value(std::forward<T>(t))
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
!IsLvalueReference<H> || (
|
!IsLvalueReference<H> || (
|
||||||
|
@ -97,7 +97,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 1>, A const &a, T &&t):
|
explicit TupleLeaf(Constant<int, 1>, A const &a, T &&t):
|
||||||
p_value(allocator_arg, a, forward<T>(t))
|
p_value(allocator_arg, a, std::forward<T>(t))
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
!IsLvalueReference<H> || (
|
!IsLvalueReference<H> || (
|
||||||
|
@ -114,7 +114,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 2>, A const &a, T &&t):
|
explicit TupleLeaf(Constant<int, 2>, A const &a, T &&t):
|
||||||
p_value(forward<T>(t), a)
|
p_value(std::forward<T>(t), a)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
!IsLvalueReference<H> || (
|
!IsLvalueReference<H> || (
|
||||||
|
@ -134,7 +134,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
TupleLeaf &operator=(T &&t) {
|
TupleLeaf &operator=(T &&t) {
|
||||||
p_value = forward<T>(t);
|
p_value = std::forward<T>(t);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,21 +168,21 @@ namespace detail {
|
||||||
template<typename T, typename = EnableIf<
|
template<typename T, typename = EnableIf<
|
||||||
!IsSame<Decay<T>, TupleLeaf> && IsConstructible<H, T>
|
!IsSame<Decay<T>, TupleLeaf> && IsConstructible<H, T>
|
||||||
>>
|
>>
|
||||||
explicit TupleLeaf(T &&t): H(forward<T>(t)) {}
|
explicit TupleLeaf(T &&t): H(std::forward<T>(t)) {}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 0>, A const &, T &&t):
|
explicit TupleLeaf(Constant<int, 0>, A const &, T &&t):
|
||||||
H(forward<T>(t))
|
H(std::forward<T>(t))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 1>, A const &a, T &&t):
|
explicit TupleLeaf(Constant<int, 1>, A const &a, T &&t):
|
||||||
H(allocator_arg, a, forward<T>(t))
|
H(allocator_arg, a, std::forward<T>(t))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(Constant<int, 2>, A const &a, T &&t):
|
explicit TupleLeaf(Constant<int, 2>, A const &a, T &&t):
|
||||||
H(forward<T>(t), a)
|
H(std::forward<T>(t), a)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TupleLeaf(TupleLeaf const &) = default;
|
TupleLeaf(TupleLeaf const &) = default;
|
||||||
|
@ -190,7 +190,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
TupleLeaf &operator=(T &&t) {
|
TupleLeaf &operator=(T &&t) {
|
||||||
H::operator=(forward<T>(t));
|
H::operator=(std::forward<T>(t));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ namespace detail {
|
||||||
TupleIndices<Ia...>, TupleTypes<Aa...>,
|
TupleIndices<Ia...>, TupleTypes<Aa...>,
|
||||||
TupleIndices<Ib...>, TupleTypes<Ab...>, T &&...t
|
TupleIndices<Ib...>, TupleTypes<Ab...>, T &&...t
|
||||||
):
|
):
|
||||||
TupleLeaf<Ia, Aa>(forward<T>(t))...,
|
TupleLeaf<Ia, Aa>(std::forward<T>(t))...,
|
||||||
TupleLeaf<Ib, Ab>()...
|
TupleLeaf<Ib, Ab>()...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ namespace detail {
|
||||||
):
|
):
|
||||||
TupleLeaf<Ia, Aa>(
|
TupleLeaf<Ia, Aa>(
|
||||||
UsesAllocatorConstructor<Aa, Alloc, T>, a,
|
UsesAllocatorConstructor<Aa, Alloc, T>, a,
|
||||||
forward<T>(t)
|
std::forward<T>(t)
|
||||||
)...,
|
)...,
|
||||||
TupleLeaf<Ib, Ab>(UsesAllocatorConstructor<Ab, Alloc>, a)...
|
TupleLeaf<Ib, Ab>(UsesAllocatorConstructor<Ab, Alloc>, a)...
|
||||||
{}
|
{}
|
||||||
|
@ -269,7 +269,7 @@ namespace detail {
|
||||||
>>
|
>>
|
||||||
TupleBase(T &&t):
|
TupleBase(T &&t):
|
||||||
TupleLeaf<I, A>(
|
TupleLeaf<I, A>(
|
||||||
forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
std::forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
||||||
)...
|
)...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -280,14 +280,14 @@ namespace detail {
|
||||||
TupleLeaf<I, A>(
|
TupleLeaf<I, A>(
|
||||||
UsesAllocatorConstructor<
|
UsesAllocatorConstructor<
|
||||||
A, Alloc, TupleElement<I, MakeTupleTypes<T>>
|
A, Alloc, TupleElement<I, MakeTupleTypes<T>>
|
||||||
>, a, forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
>, a, std::forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
||||||
)...
|
)...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EnableIf<TupleAssignable<T, Tuple<A...>>, TupleBase &> operator=(T &&t) {
|
EnableIf<TupleAssignable<T, Tuple<A...>>, TupleBase &> operator=(T &&t) {
|
||||||
tuple_swallow(TupleLeaf<I, A>::operator=(
|
tuple_swallow(TupleLeaf<I, A>::operator=(
|
||||||
forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
std::forward<TupleElement<I, MakeTupleTypes<T>>>(get<I>(t))
|
||||||
)...);
|
)...);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ namespace detail {
|
||||||
|
|
||||||
TupleBase &operator=(TupleBase &&t) {
|
TupleBase &operator=(TupleBase &&t) {
|
||||||
tuple_swallow(TupleLeaf<I, A>::operator=(
|
tuple_swallow(TupleLeaf<I, A>::operator=(
|
||||||
forward<A>((static_cast<TupleLeaf<I, A> &>(t)).get())
|
std::forward<A>((static_cast<TupleLeaf<I, A> &>(t)).get())
|
||||||
)...);
|
)...);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ public:
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
||||||
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
||||||
forward<T>(t)...
|
std::forward<T>(t)...
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ public:
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
||||||
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
||||||
forward<T>(t)...
|
std::forward<T>(t)...
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -440,31 +440,31 @@ public:
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(T)>(),
|
||||||
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleIndices<sizeof...(A), sizeof...(T)>(),
|
||||||
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
detail::MakeTupleTypes<Tuple, sizeof...(A), sizeof...(T)>(),
|
||||||
forward<T>(t)...
|
std::forward<T>(t)...
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, EnableIf<
|
template<typename T, EnableIf<
|
||||||
detail::TupleConvertible<T, Tuple>, bool
|
detail::TupleConvertible<T, Tuple>, bool
|
||||||
> = true>
|
> = true>
|
||||||
Tuple(T &&t): p_base(forward<T>(t)) {}
|
Tuple(T &&t): p_base(std::forward<T>(t)) {}
|
||||||
|
|
||||||
template<typename T, EnableIf<
|
template<typename T, EnableIf<
|
||||||
detail::TupleConstructible<T, Tuple> &&
|
detail::TupleConstructible<T, Tuple> &&
|
||||||
!detail::TupleConvertible<T, Tuple>, bool
|
!detail::TupleConvertible<T, Tuple>, bool
|
||||||
> = true>
|
> = true>
|
||||||
Tuple(T &&t): p_base(forward<T>(t)) {}
|
Tuple(T &&t): p_base(std::forward<T>(t)) {}
|
||||||
|
|
||||||
template<typename Alloc, typename T, typename = EnableIf<
|
template<typename Alloc, typename T, typename = EnableIf<
|
||||||
detail::TupleConvertible<T, Tuple>
|
detail::TupleConvertible<T, Tuple>
|
||||||
>>
|
>>
|
||||||
Tuple(AllocatorArg, Alloc const &a, T &&t):
|
Tuple(AllocatorArg, Alloc const &a, T &&t):
|
||||||
p_base(allocator_arg, a, forward<T>(t))
|
p_base(allocator_arg, a, std::forward<T>(t))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename = EnableIf<detail::TupleAssignable<T, Tuple>>>
|
template<typename T, typename = EnableIf<detail::TupleAssignable<T, Tuple>>>
|
||||||
Tuple &operator=(T &&t) {
|
Tuple &operator=(T &&t) {
|
||||||
p_base.operator=(forward<T>(t));
|
p_base.operator=(std::forward<T>(t));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,14 +548,14 @@ namespace detail {
|
||||||
|
|
||||||
template<typename ...T>
|
template<typename ...T>
|
||||||
inline Tuple<typename detail::MakeTupleReturn<T>::Type...> make_tuple(T &&...t) {
|
inline Tuple<typename detail::MakeTupleReturn<T>::Type...> make_tuple(T &&...t) {
|
||||||
return Tuple<typename detail::MakeTupleReturn<T>::Type...>(forward<T>(t)...);
|
return Tuple<typename detail::MakeTupleReturn<T>::Type...>(std::forward<T>(t)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forward as tuple */
|
/* forward as tuple */
|
||||||
|
|
||||||
template<typename ...T>
|
template<typename ...T>
|
||||||
inline Tuple<T &&...> forward_as_tuple(T &&...t) {
|
inline Tuple<T &&...> forward_as_tuple(T &&...t) {
|
||||||
return Tuple<T &&...>(forward<T>(t)...);
|
return Tuple<T &&...>(std::forward<T>(t)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tuple relops */
|
/* tuple relops */
|
||||||
|
@ -642,7 +642,10 @@ Pair<T, U>::Pair(
|
||||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||||
):
|
):
|
||||||
first(forward<A1>(get<I1>(fa))...), second(forward<A2>(get<I2>(sa))...)
|
first(
|
||||||
|
std::forward<A1>(get<I1>(fa))...),
|
||||||
|
second(std::forward<A2>(get<I2>(sa))...
|
||||||
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -652,8 +655,8 @@ namespace detail {
|
||||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||||
):
|
):
|
||||||
p_first(forward<A1>(get<I1>(fa))...),
|
p_first(std::forward<A1>(get<I1>(fa))...),
|
||||||
p_second(forward<A2>(get<I2>(sa))...)
|
p_second(std::forward<A2>(get<I2>(sa))...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -662,8 +665,8 @@ namespace detail {
|
||||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||||
):
|
):
|
||||||
T(forward<A1>(get<I1>(fa))...),
|
T(std::forward<A1>(get<I1>(fa))...),
|
||||||
p_second(forward<A2>(get<I2>(sa))...)
|
p_second(std::forward<A2>(get<I2>(sa))...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -672,8 +675,8 @@ namespace detail {
|
||||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||||
):
|
):
|
||||||
U(forward<A2>(get<I2>(sa))...),
|
U(std::forward<A2>(get<I2>(sa))...),
|
||||||
p_first(forward<A1>(get<I1>(fa))...)
|
p_first(std::forward<A1>(get<I1>(fa))...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -682,8 +685,8 @@ namespace detail {
|
||||||
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
PiecewiseConstruct, Tuple<A1...> &fa, Tuple<A2...> &sa,
|
||||||
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
detail::TupleIndices<I1...>, detail::TupleIndices<I2...>
|
||||||
):
|
):
|
||||||
T(forward<A1>(get<I1>(fa))...),
|
T(std::forward<A1>(get<I1>(fa))...),
|
||||||
U(forward<A2>(get<I2>(sa))...)
|
U(std::forward<A2>(get<I2>(sa))...)
|
||||||
{}
|
{}
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
|
|
|
@ -8,39 +8,13 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "ostd/type_traits.hh"
|
#include "ostd/type_traits.hh"
|
||||||
#include "ostd/internal/tuple.hh"
|
#include "ostd/internal/tuple.hh"
|
||||||
|
|
||||||
namespace ostd {
|
namespace ostd {
|
||||||
|
|
||||||
/* move */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr RemoveReference<T> &&move(T &&v) noexcept {
|
|
||||||
return static_cast<RemoveReference<T> &&>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* forward */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr T &&forward(RemoveReference<T> &v) noexcept {
|
|
||||||
return static_cast<T &&>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr T &&forward(RemoveReference<T> &&v) noexcept {
|
|
||||||
return static_cast<T &&>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* exchange */
|
|
||||||
|
|
||||||
template<typename T, typename U = T>
|
|
||||||
inline T exchange(T &v, U &&nv) {
|
|
||||||
T old = move(v);
|
|
||||||
v = forward<U>(nv);
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* declval */
|
/* declval */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -66,9 +40,9 @@ namespace detail {
|
||||||
inline void swap_fb(
|
inline void swap_fb(
|
||||||
T &a, T &b, EnableIf<!decltype(test_swap<T>(0))::value, bool> = true
|
T &a, T &b, EnableIf<!decltype(test_swap<T>(0))::value, bool> = true
|
||||||
) noexcept(IsNothrowMoveConstructible<T> && IsNothrowMoveAssignable<T>) {
|
) noexcept(IsNothrowMoveConstructible<T> && IsNothrowMoveAssignable<T>) {
|
||||||
T c(move(a));
|
T c(std::move(a));
|
||||||
a = move(b);
|
a = std::move(b);
|
||||||
b = move(c);
|
b = std::move(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +92,7 @@ struct Pair {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair(TT &&x, UU &&y):
|
Pair(TT &&x, UU &&y):
|
||||||
first(forward<TT>(x)), second(forward<UU>(y))
|
first(std::forward<TT>(x)), second(std::forward<UU>(y))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
|
@ -126,7 +100,7 @@ struct Pair {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair(Pair<TT, UU> &&v):
|
Pair(Pair<TT, UU> &&v):
|
||||||
first(move(v.first)), second(move(v.second))
|
first(std::move(v.first)), second(std::move(v.second))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2>
|
template<typename ...A1, typename ...A2>
|
||||||
|
@ -154,15 +128,15 @@ struct Pair {
|
||||||
Pair &operator=(Pair &&v) noexcept(
|
Pair &operator=(Pair &&v) noexcept(
|
||||||
IsNothrowMoveAssignable<T> && IsNothrowMoveAssignable<U>
|
IsNothrowMoveAssignable<T> && IsNothrowMoveAssignable<U>
|
||||||
) {
|
) {
|
||||||
first = move(v.first);
|
first = std::move(v.first);
|
||||||
second = move(v.second);
|
second = std::move(v.second);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair &operator=(Pair<TT, UU> &&v) {
|
Pair &operator=(Pair<TT, UU> &&v) {
|
||||||
first = forward<TT>(v.first);
|
first = std::forward<TT>(v.first);
|
||||||
second = forward<UU>(v.second);
|
second = std::forward<UU>(v.second);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +183,7 @@ inline Pair<
|
||||||
return Pair<
|
return Pair<
|
||||||
typename detail::MakePairRet<T>::Type,
|
typename detail::MakePairRet<T>::Type,
|
||||||
typename detail::MakePairRet<U>::Type
|
typename detail::MakePairRet<U>::Type
|
||||||
>(forward<T>(a), forward<U>(b));
|
>(std::forward<T>(a), std::forward<U>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -272,10 +246,10 @@ namespace detail {
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static T const &get(Pair<T, U> const &p) { return p.first; }
|
static T const &get(Pair<T, U> const &p) { return p.first; }
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static T &&get(Pair<T, U> &&p) { return forward<T>(p.first); }
|
static T &&get(Pair<T, U> &&p) { return std::forward<T>(p.first); }
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static T const &&get(Pair<T, U> const &&p) {
|
static T const &&get(Pair<T, U> const &&p) {
|
||||||
return forward<T const>(p.first);
|
return std::forward<T const>(p.first);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -286,10 +260,10 @@ namespace detail {
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static U const &get(Pair<T, U> const &p) { return p.second; }
|
static U const &get(Pair<T, U> const &p) { return p.second; }
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static U &&get(Pair<T, U> &&p) { return forward<U>(p.second); }
|
static U &&get(Pair<T, U> &&p) { return std::forward<U>(p.second); }
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static T const &&get(Pair<T, U> const &&p) {
|
static T const &&get(Pair<T, U> const &&p) {
|
||||||
return forward<T const>(p.second);
|
return std::forward<T const>(p.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -306,12 +280,12 @@ inline TupleElement<I, Pair<T, U>> const &get(Pair<T, U> const &p) noexcept {
|
||||||
|
|
||||||
template<Size I, typename T, typename U>
|
template<Size I, typename T, typename U>
|
||||||
inline TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&p) noexcept {
|
inline TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&p) noexcept {
|
||||||
return detail::GetPair<I>::get(move(p));
|
return detail::GetPair<I>::get(std::move(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Size I, typename T, typename U>
|
template<Size I, typename T, typename U>
|
||||||
inline TupleElement<I, Pair<T, U>> const &&get(Pair<T, U> const &&p) noexcept {
|
inline TupleElement<I, Pair<T, U>> const &&get(Pair<T, U> const &&p) noexcept {
|
||||||
return detail::GetPair<I>::get(move(p));
|
return detail::GetPair<I>::get(std::move(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -351,7 +325,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
CompressedPairBase(TT &&a, UU &&b):
|
CompressedPairBase(TT &&a, UU &&b):
|
||||||
p_first(forward<TT>(a)), p_second(forward<UU>(b))
|
p_first(std::forward<TT>(a)), p_second(std::forward<UU>(b))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||||
|
@ -378,7 +352,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
CompressedPairBase(TT &&a, UU &&b):
|
CompressedPairBase(TT &&a, UU &&b):
|
||||||
T(forward<TT>(a)), p_second(forward<UU>(b))
|
T(std::forward<TT>(a)), p_second(std::forward<UU>(b))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||||
|
@ -404,7 +378,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
CompressedPairBase(TT &&a, UU &&b):
|
CompressedPairBase(TT &&a, UU &&b):
|
||||||
U(forward<UU>(b)), p_first(forward<TT>(a))
|
U(std::forward<UU>(b)), p_first(std::forward<TT>(a))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||||
|
@ -428,7 +402,7 @@ namespace detail {
|
||||||
struct CompressedPairBase<T, U, 3>: T, U {
|
struct CompressedPairBase<T, U, 3>: T, U {
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
CompressedPairBase(TT &&a, UU &&b):
|
CompressedPairBase(TT &&a, UU &&b):
|
||||||
T(forward<TT>(a)), U(forward<UU>(b))
|
T(std::forward<TT>(a)), U(std::forward<UU>(b))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
template<typename ...A1, typename ...A2, Size ...I1, Size ...I2>
|
||||||
|
@ -452,7 +426,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
CompressedPair(TT &&a, UU &&b):
|
CompressedPair(TT &&a, UU &&b):
|
||||||
Base(forward<TT>(a), forward<UU>(b))
|
Base(std::forward<TT>(a), std::forward<UU>(b))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename ...A1, typename ...A2>
|
template<typename ...A1, typename ...A2>
|
||||||
|
|
510
ostd/vector.hh
510
ostd/vector.hh
|
@ -1,4 +1,4 @@
|
||||||
/* Self-expanding dynamic array implementation for OctaSTD.
|
/* OctaSTD extensions for std::vector.
|
||||||
*
|
*
|
||||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||||
*/
|
*/
|
||||||
|
@ -6,504 +6,40 @@
|
||||||
#ifndef OSTD_VECTOR_HH
|
#ifndef OSTD_VECTOR_HH
|
||||||
#define OSTD_VECTOR_HH
|
#define OSTD_VECTOR_HH
|
||||||
|
|
||||||
#include <string.h>
|
#include <vector>
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "ostd/type_traits.hh"
|
|
||||||
#include "ostd/utility.hh"
|
|
||||||
#include "ostd/range.hh"
|
#include "ostd/range.hh"
|
||||||
#include "ostd/algorithm.hh"
|
|
||||||
#include "ostd/initializer_list.hh"
|
|
||||||
#include "ostd/memory.hh"
|
|
||||||
|
|
||||||
namespace ostd {
|
namespace ostd {
|
||||||
|
|
||||||
template<typename T, typename A = Allocator<T>>
|
template<typename T>
|
||||||
class Vector {
|
inline PointerRange<T> iter(std::vector<T> &v) {
|
||||||
using VecPair = detail::CompressedPair<AllocatorPointer<A>, A>;
|
return PointerRange<T>{v.data(), v.size()};
|
||||||
|
|
||||||
ostd::Size p_len, p_cap;
|
|
||||||
VecPair p_buf;
|
|
||||||
|
|
||||||
void insert_base(Size idx, Size n) {
|
|
||||||
if (p_len + n > p_cap) {
|
|
||||||
reserve(p_len + n);
|
|
||||||
}
|
|
||||||
p_len += n;
|
|
||||||
for (Size i = p_len - 1; i > idx + n - 1; --i) {
|
|
||||||
p_buf.first()[i] = move(p_buf.first()[i - n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R>
|
|
||||||
void ctor_from_range(
|
|
||||||
R &range, EnableIf<
|
|
||||||
IsFiniteRandomAccessRange<R> && IsPod<T> &&
|
|
||||||
IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
|
||||||
> = true
|
|
||||||
) {
|
|
||||||
RangeSize<R> l = range.size();
|
|
||||||
reserve(l);
|
|
||||||
p_len = l;
|
|
||||||
range.copy(p_buf.first(), l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R>
|
|
||||||
void ctor_from_range(
|
|
||||||
R &range, EnableIf<
|
|
||||||
!IsFiniteRandomAccessRange<R> || !IsPod<T> ||
|
|
||||||
!IsSame<T, RemoveCv<RangeValue<R>>>, bool
|
|
||||||
> = true
|
|
||||||
) {
|
|
||||||
Size i = 0;
|
|
||||||
for (; !range.empty(); range.pop_front()) {
|
|
||||||
reserve(i + 1);
|
|
||||||
allocator_construct(
|
|
||||||
p_buf.second(), &p_buf.first()[i], range.front()
|
|
||||||
);
|
|
||||||
++i;
|
|
||||||
p_len = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_contents(Vector const &v) {
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
|
||||||
} else {
|
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
|
||||||
Pointer vbuf = v.p_buf.first();
|
|
||||||
while (cur != last) {
|
|
||||||
allocator_construct(p_buf.second(), cur++, *vbuf++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
using Size = ostd::Size;
|
|
||||||
using Difference = Ptrdiff;
|
|
||||||
using Value = T;
|
|
||||||
using Reference = T &;
|
|
||||||
using ConstReference = T const &;
|
|
||||||
using Pointer = AllocatorPointer<A>;
|
|
||||||
using ConstPointer = AllocatorConstPointer<A>;
|
|
||||||
using Range = PointerRange<T>;
|
|
||||||
using ConstRange = PointerRange<T const>;
|
|
||||||
using Allocator = A;
|
|
||||||
|
|
||||||
Vector(A const &a = A()): p_len(0), p_cap(0), p_buf(nullptr, a) {}
|
|
||||||
|
|
||||||
explicit Vector(Size n, T const &val = T(), A const &al = A()): Vector(al) {
|
|
||||||
if (!n) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p_buf.first() = allocator_allocate(p_buf.second(), n);
|
|
||||||
p_len = p_cap = n;
|
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + n;
|
|
||||||
while (cur != last) {
|
|
||||||
allocator_construct(p_buf.second(), cur++, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(Vector const &v):
|
|
||||||
p_len(0), p_cap(0), p_buf(nullptr, allocator_container_copy(
|
|
||||||
v.p_buf.second())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
reserve(v.p_cap);
|
|
||||||
p_len = v.p_len;
|
|
||||||
copy_contents(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(Vector const &v, A const &a): p_len(0), p_cap(0), p_buf(nullptr, a) {
|
|
||||||
reserve(v.p_cap);
|
|
||||||
p_len = v.p_len;
|
|
||||||
copy_contents(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(Vector &&v):
|
|
||||||
p_len(v.p_len), p_cap(v.p_cap), p_buf(
|
|
||||||
v.p_buf.first(), move(v.p_buf.second())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
v.p_buf.first() = nullptr;
|
|
||||||
v.p_len = v.p_cap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(Vector &&v, A const &a): p_len(0), p_cap(0), p_buf(nullptr, a) {
|
|
||||||
if (a != v.p_buf.second()) {
|
|
||||||
reserve(v.p_cap);
|
|
||||||
p_len = v.p_len;
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
|
||||||
} else {
|
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
|
||||||
Pointer vbuf = v.p_buf.first();
|
|
||||||
while (cur != last) {
|
|
||||||
allocator_construct(p_buf.second(), cur++, move(*vbuf++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p_buf.first() = v.p_buf.first();
|
|
||||||
p_len = v.p_len;
|
|
||||||
p_cap = v.p_cap;
|
|
||||||
v.p_buf.first() = nullptr;
|
|
||||||
v.p_len = v.p_cap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(ConstRange r, A const &a = A()): Vector(a) {
|
|
||||||
reserve(r.size());
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(p_buf.first(), &r[0], r.size() * sizeof(T));
|
|
||||||
} else {
|
|
||||||
for (Size i = 0; i < r.size(); ++i) {
|
|
||||||
allocator_construct(p_buf.second(), &p_buf.first()[i], r[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p_len = r.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(std::initializer_list<T> v, A const &a = A()):
|
|
||||||
Vector(ConstRange(v.begin(), v.size()), a)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
|
||||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
|
||||||
>>
|
|
||||||
Vector(R range, A const &a = A()): Vector(a) {
|
|
||||||
ctor_from_range(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Vector() {
|
|
||||||
clear();
|
|
||||||
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
if (p_len > 0 && !IsPod<T>) {
|
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
|
||||||
while (cur != last) {
|
|
||||||
allocator_destroy(p_buf.second(), cur++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector &operator=(Vector const &v) {
|
|
||||||
if (this == &v) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
clear();
|
|
||||||
if (AllocatorPropagateOnContainerCopyAssignment<A>) {
|
|
||||||
if (p_buf.second() != v.p_buf.second() && p_cap) {
|
|
||||||
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
|
|
||||||
p_cap = 0;
|
|
||||||
}
|
|
||||||
p_buf.second() = v.p_buf.second();
|
|
||||||
}
|
|
||||||
reserve(v.p_cap);
|
|
||||||
p_len = v.p_len;
|
|
||||||
copy_contents(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector &operator=(Vector &&v) {
|
|
||||||
clear();
|
|
||||||
if (p_buf.first()) {
|
|
||||||
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
|
|
||||||
}
|
|
||||||
if (AllocatorPropagateOnContainerMoveAssignment<A>) {
|
|
||||||
p_buf.second() = v.p_buf.second();
|
|
||||||
}
|
|
||||||
p_len = v.p_len;
|
|
||||||
p_cap = v.p_cap;
|
|
||||||
p_buf.~VecPair();
|
|
||||||
new (&p_buf) VecPair(v.release(), move(v.p_buf.second()));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector &operator=(std::initializer_list<T> il) {
|
|
||||||
clear();
|
|
||||||
Size ilen = il.end() - il.begin();
|
|
||||||
reserve(ilen);
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(p_buf.first(), il.begin(), ilen);
|
|
||||||
} else {
|
|
||||||
Pointer tbuf = p_buf.first(), ibuf = il.begin(),
|
|
||||||
last = il.end();
|
|
||||||
while (ibuf != last) {
|
|
||||||
allocator_construct(p_buf.second(),
|
|
||||||
tbuf++, *ibuf++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p_len = ilen;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename = EnableIf<
|
|
||||||
IsInputRange<R> && IsConvertible<RangeReference<R>, Value>
|
|
||||||
>>
|
|
||||||
Vector &operator=(R range) {
|
|
||||||
clear();
|
|
||||||
ctor_from_range(range);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(Size n, T const &v = T()) {
|
|
||||||
if (!n) {
|
|
||||||
clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Size l = p_len;
|
|
||||||
reserve(n);
|
|
||||||
p_len = n;
|
|
||||||
if (IsPod<T>) {
|
|
||||||
for (Size i = l; i < p_len; ++i) {
|
|
||||||
p_buf.first()[i] = T(v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Pointer first = p_buf.first() + l;
|
|
||||||
Pointer last = p_buf.first() + p_len;
|
|
||||||
while (first != last) {
|
|
||||||
allocator_construct(p_buf.second(), first++, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(Size n) {
|
|
||||||
if (n <= p_cap) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Size oc = p_cap;
|
|
||||||
if (!oc) {
|
|
||||||
p_cap = max(n, Size(8));
|
|
||||||
} else {
|
|
||||||
while (p_cap < n) p_cap *= 2;
|
|
||||||
}
|
|
||||||
Pointer tmp = allocator_allocate(p_buf.second(), p_cap);
|
|
||||||
if (oc > 0) {
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(tmp, p_buf.first(), p_len * sizeof(T));
|
|
||||||
} else {
|
|
||||||
Pointer cur = p_buf.first(), tcur = tmp,
|
|
||||||
last = tmp + p_len;
|
|
||||||
while (tcur != last) {
|
|
||||||
allocator_construct(p_buf.second(), tcur++, move(*cur));
|
|
||||||
allocator_destroy(p_buf.second(), cur);
|
|
||||||
++cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allocator_deallocate(p_buf.second(), p_buf.first(), oc);
|
|
||||||
}
|
|
||||||
p_buf.first() = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
T &operator[](Size i) { return p_buf.first()[i]; }
|
|
||||||
T const &operator[](Size i) const { return p_buf.first()[i]; }
|
|
||||||
|
|
||||||
T *at(Size i) {
|
|
||||||
if (!in_range(i)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return &p_buf.first()[i];
|
|
||||||
}
|
|
||||||
T const *at(Size i) const {
|
|
||||||
if (!in_range(i)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return &p_buf.first()[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
T &push(T const &v) {
|
|
||||||
if (p_len == p_cap) {
|
|
||||||
reserve(p_len + 1);
|
|
||||||
}
|
|
||||||
allocator_construct(p_buf.second(), &p_buf.first()[p_len], v);
|
|
||||||
return p_buf.first()[p_len++];
|
|
||||||
}
|
|
||||||
|
|
||||||
T &push(T &&v) {
|
|
||||||
if (p_len == p_cap) {
|
|
||||||
reserve(p_len + 1);
|
|
||||||
}
|
|
||||||
allocator_construct(p_buf.second(), &p_buf.first()[p_len], move(v));
|
|
||||||
return p_buf.first()[p_len++];
|
|
||||||
}
|
|
||||||
|
|
||||||
T &push() {
|
|
||||||
if (p_len == p_cap) {
|
|
||||||
reserve(p_len + 1);
|
|
||||||
}
|
|
||||||
allocator_construct(p_buf.second(), &p_buf.first()[p_len]);
|
|
||||||
return p_buf.first()[p_len++];
|
|
||||||
}
|
|
||||||
|
|
||||||
Range push_n(T const *v, Size n) {
|
|
||||||
reserve(p_len + n);
|
|
||||||
if (IsPod<T>) {
|
|
||||||
memcpy(p_buf.first() + p_len, v, n * sizeof(T));
|
|
||||||
} else {
|
|
||||||
for (Size i = 0; i < n; ++i) {
|
|
||||||
allocator_construct(
|
|
||||||
p_buf.second(), &p_buf.first()[p_len + i], v[i]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p_len += n;
|
|
||||||
return Range(&p_buf.first()[p_len - n], &p_buf.first()[p_len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...U>
|
|
||||||
T &emplace_back(U &&...args) {
|
|
||||||
if (p_len == p_cap) {
|
|
||||||
reserve(p_len + 1);
|
|
||||||
}
|
|
||||||
allocator_construct(
|
|
||||||
p_buf.second(), &p_buf.first()[p_len], forward<U>(args)...
|
|
||||||
);
|
|
||||||
return p_buf.first()[p_len++];
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
|
||||||
if (!IsPod<T>) {
|
|
||||||
allocator_destroy(p_buf.second(), &p_buf.first()[--p_len]);
|
|
||||||
} else {
|
|
||||||
--p_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T &front() { return p_buf.first()[0]; }
|
|
||||||
T const &front() const { return p_buf.first()[0]; }
|
|
||||||
|
|
||||||
T &back() { return p_buf.first()[p_len - 1]; }
|
|
||||||
T const &back() const { return p_buf.first()[p_len - 1]; }
|
|
||||||
|
|
||||||
Value *data() { return reinterpret_cast<Value *>(p_buf.first()); }
|
|
||||||
Value const *data() const {
|
|
||||||
return reinterpret_cast<Value const *>(p_buf.first());
|
|
||||||
}
|
|
||||||
|
|
||||||
Size size() const { return p_len; }
|
|
||||||
Size capacity() const { return p_cap; }
|
|
||||||
|
|
||||||
void advance(Size s) { p_len += s; }
|
|
||||||
|
|
||||||
Size max_size() const { return Size(~0) / sizeof(T); }
|
|
||||||
|
|
||||||
bool empty() const { return (p_len == 0); }
|
|
||||||
|
|
||||||
bool in_range(Size idx) { return idx < p_len; }
|
|
||||||
bool in_range(int idx) { return idx >= 0 && Size(idx) < p_len; }
|
|
||||||
bool in_range(Value const *ptr) {
|
|
||||||
return ptr >= p_buf.first() && ptr < &p_buf.first()[p_len];
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *release() {
|
|
||||||
Pointer r = p_buf.first();
|
|
||||||
p_buf.first() = nullptr;
|
|
||||||
p_len = p_cap = 0;
|
|
||||||
return reinterpret_cast<Value *>(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range insert(Size idx, T &&v) {
|
|
||||||
insert_base(idx, 1);
|
|
||||||
p_buf.first()[idx] = move(v);
|
|
||||||
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range insert(Size idx, T const &v) {
|
|
||||||
insert_base(idx, 1);
|
|
||||||
p_buf.first()[idx] = v;
|
|
||||||
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range insert(Size idx, Size n, T const &v) {
|
|
||||||
insert_base(idx, n);
|
|
||||||
for (Size i = 0; i < n; ++i) {
|
|
||||||
p_buf.first()[idx + i] = v;
|
|
||||||
}
|
|
||||||
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
Range insert_range(Size idx, U range) {
|
|
||||||
Size l = range.size();
|
|
||||||
insert_base(idx, l);
|
|
||||||
for (Size i = 0; i < l; ++i) {
|
|
||||||
p_buf.first()[idx + i] = range.front();
|
|
||||||
range.pop_front();
|
|
||||||
}
|
|
||||||
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range insert(Size idx, std::initializer_list<T> il) {
|
|
||||||
return insert_range(idx, ostd::iter(il));
|
|
||||||
}
|
|
||||||
|
|
||||||
Range iter() {
|
|
||||||
return Range(p_buf.first(), p_buf.first() + p_len);
|
|
||||||
}
|
|
||||||
ConstRange iter() const {
|
|
||||||
return ConstRange(p_buf.first(), p_buf.first() + p_len);
|
|
||||||
}
|
|
||||||
ConstRange citer() const {
|
|
||||||
return ConstRange(p_buf.first(), p_buf.first() + p_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range iter_cap() {
|
|
||||||
return Range(p_buf.first(), p_buf.first() + p_cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(Vector &v) {
|
|
||||||
detail::swap_adl(p_len, v.p_len);
|
|
||||||
detail::swap_adl(p_cap, v.p_cap);
|
|
||||||
detail::swap_adl(p_buf.first(), v.p_buf.first());
|
|
||||||
if (AllocatorPropagateOnContainerSwap<A>) {
|
|
||||||
detail::swap_adl(p_buf.second(), v.p_buf.second());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
A get_allocator() const {
|
|
||||||
return p_buf.second();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename A>
|
|
||||||
inline bool operator==(Vector<T, A> const &x, Vector<T, A> const &y) {
|
|
||||||
return equal(x.iter(), y.iter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool operator!=(Vector<T, A> const &x, Vector<T, A> const &y) {
|
inline PointerRange<T const> iter(std::vector<T> const &v) {
|
||||||
return !(x == y);
|
return PointerRange<T const>{v.data(), v.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool operator<(Vector<T, A> const &x, Vector<T, A> const &y) {
|
inline PointerRange<T const> citer(std::vector<T> const &v) {
|
||||||
using Range = typename Vector<T, A>::Range;
|
return PointerRange<T const>{v.data(), v.size()};
|
||||||
Range range1 = x.iter(), range2 = y.iter();
|
}
|
||||||
while (!range1.empty() && !range2.empty()) {
|
|
||||||
if (range1.front() < range2.front()) return true;
|
template<typename T, typename R>
|
||||||
if (range2.front() < range1.front()) return false;
|
inline std::vector<T> make_vector(R range) {
|
||||||
range1.pop_front();
|
/* TODO: specialize for contiguous ranges and matching value types */
|
||||||
range2.pop_front();
|
std::vector<T> ret;
|
||||||
|
for (; !range.empty(); range.pop_front()) {
|
||||||
|
ret.push_back(range.front());
|
||||||
}
|
}
|
||||||
return (range1.empty() && !range2.empty());
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename R>
|
||||||
inline bool operator>(Vector<T, A> const &x, Vector<T, A> const &y) {
|
inline std::vector<RangeValue<R>> make_vector(R range) {
|
||||||
return (y < x);
|
return make_vector<RangeValue<R>>(std::move(range));
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename A>
|
|
||||||
inline bool operator<=(Vector<T, A> const &x, Vector<T, A> const &y) {
|
|
||||||
return !(y < x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename A>
|
|
||||||
inline bool operator>=(Vector<T, A> const &x, Vector<T, A> const &y) {
|
|
||||||
return !(x < y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
Loading…
Reference in a new issue