diff --git a/examples/format.cc b/examples/format.cc index 4752850..8f31f10 100644 --- a/examples/format.cc +++ b/examples/format.cc @@ -1,9 +1,9 @@ +#include +#include #include #include #include -#include -#include #include #include diff --git a/examples/range.cc b/examples/range.cc index b79ee20..73f90ab 100644 --- a/examples/range.cc +++ b/examples/range.cc @@ -1,7 +1,8 @@ +#include + #include #include #include -#include using namespace ostd; @@ -27,7 +28,8 @@ int main() { /* prints ABCDEF (ASCII 65, 66, 67, 68, 69, 70) */ writeln("string gen test"); - auto s = make_string(map(range(6), [](int v) -> char { return v + 65; })); + auto mr = map(range(6), [](int v) -> char { return v + 65; }); + std::string s{mr.iter_begin(), mr.iter_end()}; writeln(s); /* join a few ranges together - prints 11, 22, 33 ... 99 each on new line */ diff --git a/examples/range_pipe.cc b/examples/range_pipe.cc index 31a11eb..9f175e1 100644 --- a/examples/range_pipe.cc +++ b/examples/range_pipe.cc @@ -23,7 +23,8 @@ int main() { /* prints ABCDEF (ASCII 65, 66, 67, 68, 69, 70) */ writeln("string gen test"); - auto s = make_string(range(6) | map([](int v) -> char { return v + 65; })); + auto mr = range(6) | map([](int v) -> char { return v + 65; }); + std::string s{mr.iter_begin(), mr.iter_end()}; writeln(s); /* join a few ranges together - prints 11, 22, 33 ... 99 each on new line */ @@ -76,15 +77,15 @@ int main() { | filter([](auto v) { return v >= 65 && v <= 90; }) | map ([](auto v) { return char(v); }); - writeln(make_string(r)); + writeln(std::string{r.iter_begin(), r.iter_end()}); /* "list comprehensions" */ writeln("list initialization"); - auto test = make_vector( - range(20) - | filter([](int v) { return v % 2 == 0; }) - | map ([](int v) { return v * 2; }) - ); + auto vr = range(20) + | filter([](int v) { return v % 2 == 0; }) + | map ([](int v) { return v * 2; }); + + std::vector test{vr.iter_begin(), vr.iter_end()}; writeln(test); } diff --git a/examples/stream2.cc b/examples/stream2.cc index f9da5a3..0aa66c1 100644 --- a/examples/stream2.cc +++ b/examples/stream2.cc @@ -1,6 +1,7 @@ +#include + #include #include -#include #include using namespace ostd; @@ -25,15 +26,21 @@ int main() { writeln("## WHOLE FILE READ ##\n"); - auto ts1 = make_string(test.iter()); - writefln("-- str beg --\n%s-- str end --", ts1); + auto fr = test.iter(); + writefln( + "-- str beg --\n%s-- str end --", + std::string{fr.iter_begin(), fr.iter_end()} + ); test.seek(0); writeln("\n## PART FILE READ ##\n"); - auto ts2 = make_string(test.iter().take(25)); - writefln("-- str beg --\n%s\n-- str end --", ts2); + auto fr2 = test.iter().take(25); + writefln( + "-- str beg --\n%s\n-- str end --", + std::string{fr2.iter_begin(), fr2.iter_end()} + ); test.seek(0); @@ -64,7 +71,8 @@ int main() { test.open("test.txt"); - auto x = make_vector(test.iter_lines()); + auto lns = test.iter_lines(); + std::vector x{lns.iter_begin(), lns.iter_end()}; writeln("before sort: ", x); sort(iter(x)); writeln("after sort: ", x); diff --git a/ostd/string.hh b/ostd/string.hh index 9977386..6ae1ee5 100644 --- a/ostd/string.hh +++ b/ostd/string.hh @@ -53,9 +53,9 @@ #include #include #include +#include #include "ostd/range.hh" -#include "ostd/vector.hh" #include "ostd/algorithm.hh" namespace ostd { @@ -618,46 +618,6 @@ struct ranged_traits const> { } }; -/** @brief Creates a string out of any generic range type. - * - * The character type of the string must be explicitly specified here. - * You can also optionally specify the character traits used for the string. - */ -template< - typename T, typename TR = std::char_traits, - typename A = std::allocator, typename R -> -inline std::basic_string make_string(R range, A const &alloc = A{}) { - std::basic_string ret{alloc}; - using C = range_category_t; - if constexpr(std::is_convertible_v) { - ret.reserve(range.size()); - ret.insert(ret.end(), range.data(), range.data() + range.size()); - } else { - for (; !range.empty(); range.pop_front()) { - ret.push_back(range.front()); - } - } - return ret; -} - -/** @brief Creates a string out of any generic range type. - * - * The character type of the string is guessed from the range type itself. - * You can also optionally specify the character traits used for the string. - */ -template< - typename R, typename TR = std::char_traits>>, - typename A = std::allocator>> -> -inline std::basic_string>, TR, A> make_string( - R range, A const &alloc = A{} -) { - return make_string>, TR, A>( - std::move(range), alloc - ); -} - /* string literals */ inline namespace literals { diff --git a/ostd/unordered_map.hh b/ostd/unordered_map.hh deleted file mode 100644 index 4ad601d..0000000 --- a/ostd/unordered_map.hh +++ /dev/null @@ -1,142 +0,0 @@ -/** @addtogroup Containers - * @{ - */ - -/** @file unordered_map.hh - * - * @brief Extensions for std::unordered_map. - * - * This file provides extensions for the standard std::unordered_map container. - * - * @copyright See COPYING.md in the project tree for further information. - */ - -#ifndef OSTD_UNORDERED_MAP_HH -#define OSTD_UNORDERED_MAP_HH - -#include -#include -#include - -#include "ostd/range.hh" - -namespace ostd { - -/** @addtogroup Containers - * @{ - */ - -namespace detail { - template - std::integral_constant< - bool, std::tuple_size::value == 2 - > tuple2_like_test(typename std::tuple_size::type *); - - template - std::false_type tuple2_like_test(...); - - template - constexpr bool is_2tuple_like = decltype(tuple2_like_test(0))::value; -} - -/** @brief Creates an unordered map using a range. - * - * The range's value type must be either an std::pair or an std::tuple - * with 2 elements, additionally the key and value types must be constructible - * using the tuple or pair's first and second element respectively. - * - * You need to manually specify the key and value types for this overload. - * - * @param[in] range The range. - * @param[in] bcount The initial bucket count. - * @param[in] hash The hash function. - * @param[in] kequal The key equality comparison function. - * @param[in] alloc The allocator. - * - * @tparam K The key type. - * @tparam V The value type. - */ -template< - typename K, typename T, typename H = std::hash, - typename E = std::equal_to, - typename A = std::allocator>, typename R -> -inline std::unordered_map make_unordered_map( - R range, std::size_t bcount = 1, H const &hash = H{}, - E const &kequal = E{}, A const &alloc = A{} -) { - static_assert( - detail::is_2tuple_like>, - "the range element must be a pair/2-tuple" - ); - - using MP = std::pair; - using AK = std::tuple_element_t<0, range_value_t>; - using AV = std::tuple_element_t<1, range_value_t>; - - static_assert( - std::is_constructible_v && std::is_constructible_v, - "incompatible range element type" - ); - - std::unordered_map ret{bcount, hash, kequal, alloc}; - - using C = range_category_t; - if constexpr(std::is_convertible_v) { - /* at least try to preallocate here... */ - ret.reserve(range.size()); - } - - for (; !range.empty(); range.pop_front()) { - if constexpr(std::is_constructible_v>) { - ret.emplace(range.front()); - } else { - /* store a temporary to prevent calling front() twice; however, - * for values that can be used to construct the pair directly - * we can just do the above - */ - range_value_t v{range.front()}; - ret.emplace(std::move(std::get<0>(v)), std::move(std::get<1>(v))); - } - } - return ret; -} - -/** @brief Creates an unordered map using a range. - * - * Calls into make_unordered_map() using the range value type's first and - * second element types as key and value respectively. - */ -template< - typename R, - typename H = std::hash::first_type>, - typename E = std::equal_to::first_type>, - typename A = std::allocator>, - std::tuple_element_t<1, range_value_t> - >> -> -inline std::unordered_map< - std::tuple_element_t<0, range_value_t>, - std::tuple_element_t<1, range_value_t>, H, E, A -> make_unordered_map( - R &&range, std::size_t bcount = 1, H const &hash = H{}, - E const &kequal = E{}, A const &alloc = A{} -) { - static_assert( - detail::is_2tuple_like>, - "the range element must be a pair/2-tuple" - ); - return make_unordered_map< - std::tuple_element_t<0, range_value_t>, - std::tuple_element_t<1, range_value_t>, H, E, A - >(std::forward(range), bcount, hash, kequal, alloc); -} - -/** @} */ - -} /* namespace ostd */ - -#endif - -/** @} */ diff --git a/ostd/vector.hh b/ostd/vector.hh deleted file mode 100644 index cd7ebbe..0000000 --- a/ostd/vector.hh +++ /dev/null @@ -1,84 +0,0 @@ -/** @defgroup Containers - * - * @brief New containers and extensions to standard containers. - * - * libostd adds various new utilities for standard containers that allow - * besides other things construction of those containers from ranges. - * - * Integration of ranges for iteration is however not necessary because - * there is already a fully generic integration for anything that provides - * an iterator interface. - * - * New containers will also be implemented where necessary. - * - * @{ - */ - -/** @file vector.hh - * - * @brief Extensions for std::vector. - * - * This file provides extensions for the standard std::vector container. - * - * @copyright See COPYING.md in the project tree for further information. - */ - -#ifndef OSTD_VECTOR_HH -#define OSTD_VECTOR_HH - -#include -#include -#include - -#include "ostd/range.hh" - -namespace ostd { - -/** @addtogroup Containers - * @{ - */ - -/** @brief Creates a vector using a range. - * - * Given a range `range` and optionally an allocator, this constructs - * an std::vector, adding each item of the given range to it. - * - * You have to manually specify the type of the vector's values. There - * is also another version with the type decided from the range. - * - * @tparam T The value type of the vector. - */ -template, typename R> -inline std::vector make_vector(R range, A const &alloc = A{}) { - std::vector ret{alloc}; - using C = range_category_t; - if constexpr(std::is_convertible_v) { - ret.reserve(range.size()); - ret.insert(ret.end(), range.data(), range.data() + range.size()); - } else { - for (; !range.empty(); range.pop_front()) { - ret.push_back(range.front()); - } - } - return ret; -} - -/** @brief Creates a vector using a range. - * - * Calls into make_vector() using the range value type as the vector - * value type. - */ -template>> -inline std::vector, A> make_vector( - R &&range, A const &alloc = A{} -) { - return make_vector, A>(std::forward(range), alloc); -} - -/** @} */ - -} /* namespace ostd */ - -#endif - -/** @} */ diff --git a/test_runner.cc b/test_runner.cc index f7c0de6..b900706 100644 --- a/test_runner.cc +++ b/test_runner.cc @@ -1,7 +1,8 @@ +#include + #include #include #include -#include #include #include