remove make_ range helpers for containers (use iter_begin/end)

master
Daniel Kolesa 2017-04-23 15:30:51 +02:00
parent ef147c538c
commit cc8452e265
8 changed files with 31 additions and 285 deletions

View File

@ -1,9 +1,9 @@
#include <unordered_map>
#include <vector>
#include <tuple>
#include <clocale>
#include <ostd/algorithm.hh>
#include <ostd/vector.hh>
#include <ostd/unordered_map.hh>
#include <ostd/range.hh>
#include <ostd/io.hh>

View File

@ -1,7 +1,8 @@
#include <vector>
#include <ostd/range.hh>
#include <ostd/io.hh>
#include <ostd/algorithm.hh>
#include <ostd/vector.hh>
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 */

View File

@ -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<int> test{vr.iter_begin(), vr.iter_end()};
writeln(test);
}

View File

@ -1,6 +1,7 @@
#include <vector>
#include <ostd/algorithm.hh>
#include <ostd/string.hh>
#include <ostd/vector.hh>
#include <ostd/io.hh>
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<std::string>(test.iter_lines());
auto lns = test.iter_lines();
std::vector<std::string> x{lns.iter_begin(), lns.iter_end()};
writeln("before sort: ", x);
sort(iter(x));
writeln("after sort: ", x);

View File

@ -53,9 +53,9 @@
#include <type_traits>
#include <functional>
#include <utility>
#include <vector>
#include "ostd/range.hh"
#include "ostd/vector.hh"
#include "ostd/algorithm.hh"
namespace ostd {
@ -618,46 +618,6 @@ struct ranged_traits<std::basic_string<T, TR, A> 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<T>,
typename A = std::allocator<T>, typename R
>
inline std::basic_string<T, TR, A> make_string(R range, A const &alloc = A{}) {
std::basic_string<T, TR, A> ret{alloc};
using C = range_category_t<R>;
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
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<std::remove_cv_t<range_value_t<R>>>,
typename A = std::allocator<std::remove_cv_t<range_value_t<R>>>
>
inline std::basic_string<std::remove_cv_t<range_value_t<R>>, TR, A> make_string(
R range, A const &alloc = A{}
) {
return make_string<std::remove_cv_t<range_value_t<R>>, TR, A>(
std::move(range), alloc
);
}
/* string literals */
inline namespace literals {

View File

@ -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 <cstddef>
#include <unordered_map>
#include <type_traits>
#include "ostd/range.hh"
namespace ostd {
/** @addtogroup Containers
* @{
*/
namespace detail {
template<typename T>
std::integral_constant<
bool, std::tuple_size<T>::value == 2
> tuple2_like_test(typename std::tuple_size<T>::type *);
template<typename>
std::false_type tuple2_like_test(...);
template<typename T>
constexpr bool is_2tuple_like = decltype(tuple2_like_test<T>(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<K>,
typename E = std::equal_to<K>,
typename A = std::allocator<std::pair<K const, T>>, typename R
>
inline std::unordered_map<K, 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<range_value_t<R>>,
"the range element must be a pair/2-tuple"
);
using MP = std::pair<K const, T>;
using AK = std::tuple_element_t<0, range_value_t<R>>;
using AV = std::tuple_element_t<1, range_value_t<R>>;
static_assert(
std::is_constructible_v<K const, AK> && std::is_constructible_v<T, AV>,
"incompatible range element type"
);
std::unordered_map<K, T, H, E, A> ret{bcount, hash, kequal, alloc};
using C = range_category_t<R>;
if constexpr(std::is_convertible_v<C, finite_random_access_range_tag>) {
/* at least try to preallocate here... */
ret.reserve(range.size());
}
for (; !range.empty(); range.pop_front()) {
if constexpr(std::is_constructible_v<MP, range_value_t<R>>) {
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<R> 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<typename range_value_t<R>::first_type>,
typename E = std::equal_to<typename range_value_t<R>::first_type>,
typename A = std::allocator<std::pair<
std::tuple_element_t<0, range_value_t<R>>,
std::tuple_element_t<1, range_value_t<R>>
>>
>
inline std::unordered_map<
std::tuple_element_t<0, range_value_t<R>>,
std::tuple_element_t<1, range_value_t<R>>, 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<range_value_t<R>>,
"the range element must be a pair/2-tuple"
);
return make_unordered_map<
std::tuple_element_t<0, range_value_t<R>>,
std::tuple_element_t<1, range_value_t<R>>, H, E, A
>(std::forward<R>(range), bcount, hash, kequal, alloc);
}
/** @} */
} /* namespace ostd */
#endif
/** @} */

View File

@ -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 <vector>
#include <memory>
#include <type_traits>
#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 T, typename A = std::allocator<T>, typename R>
inline std::vector<T, A> make_vector(R range, A const &alloc = A{}) {
std::vector<T, A> ret{alloc};
using C = range_category_t<R>;
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
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<typename R, typename A = std::allocator<range_value_t<R>>>
inline std::vector<range_value_t<R>, A> make_vector(
R &&range, A const &alloc = A{}
) {
return make_vector<range_value_t<R>, A>(std::forward<R>(range), alloc);
}
/** @} */
} /* namespace ostd */
#endif
/** @} */

View File

@ -1,7 +1,8 @@
#include <unordered_map>
#include <ostd/platform.hh>
#include <ostd/io.hh>
#include <ostd/string.hh>
#include <ostd/unordered_map.hh>
#include <ostd/filesystem.hh>
#include <ostd/environ.hh>