standard iter() for any std container type without ranged_traits

master
Daniel Kolesa 2017-02-14 18:32:51 +01:00
parent 67cbcb71eb
commit bd307bd52e
6 changed files with 43 additions and 76 deletions

View File

@ -1,6 +1,6 @@
#include <time.h>
#include <array>
#include <ctime>
#include <ostd/array.hh>
#include <ostd/range.hh>
#include <ostd/io.hh>
#include <ostd/algorithm.hh>

View File

@ -1,31 +0,0 @@
/* OctaSTD extensions for std::array.
*
* This file is part of OctaSTD. See COPYING.md for futher information.
*/
#ifndef OSTD_ARRAY_HH
#define OSTD_ARRAY_HH
#include <array>
#include "ostd/range.hh"
namespace ostd {
template<typename T, size_t N>
struct ranged_traits<std::array<T, N>> {
static IteratorRange<T *> iter(std::array<T, N> &v) {
return IteratorRange<T *>{v.data(), v.data() + N};
}
};
template<typename T, size_t N>
struct ranged_traits<std::array<T, N> const> {
static IteratorRange<T const *> iter(std::array<T, N> const &v) {
return IteratorRange<T const *>{v.data(), v.data() + N};
}
};
} /* namespace ostd */
#endif

View File

@ -23,7 +23,6 @@
#include "ostd/range.hh"
#include "ostd/vector.hh"
#include "ostd/string.hh"
#include "ostd/array.hh"
#include "ostd/algorithm.hh"
namespace ostd {

View File

@ -815,9 +815,6 @@ inline auto zip(R1 &&r1, R &&...rr) {
};
}
template<typename C, typename = void>
struct ranged_traits;
namespace detail {
template<typename C>
static std::true_type test_direct_iter(decltype(std::declval<C>().iter()) *);
@ -827,14 +824,20 @@ namespace detail {
template<typename C>
constexpr bool direct_iter_test = decltype(test_direct_iter<C>(0))::value;
template<typename C, typename = void>
struct ranged_traits_core {};
template<typename C>
struct ranged_traits_core<C, std::enable_if_t<detail::direct_iter_test<C>>> {
static auto iter(C &r) -> decltype(r.iter()) {
return r.iter();
}
};
}
template<typename C>
struct ranged_traits<C, std::enable_if_t<detail::direct_iter_test<C>>> {
static auto iter(C &r) -> decltype(r.iter()) {
return r.iter();
}
};
struct ranged_traits: detail::ranged_traits_core<C> {};
template<typename T>
inline auto iter(T &r) -> decltype(ranged_traits<T>::iter(r)) {
@ -1842,6 +1845,36 @@ inline IteratorRange<T *> iter(T *a, size_t b) {
return IteratorRange<T *>(a, a + b);
}
/* iter on standard containers */
namespace detail {
template<typename C>
static std::true_type test_std_iter(
decltype(std::begin(std::declval<C>())) *,
decltype(std::end(std::declval<C>())) *
);
template<typename>
static std::false_type test_std_iter(...);
template<typename C>
constexpr bool std_iter_test = decltype(test_std_iter<C>(0, 0))::value;
template<typename C>
struct ranged_traits_core<C, std::enable_if_t<
detail::std_iter_test<C> && !detail::direct_iter_test<C>
>> {
using range_type = std::conditional_t<
std::is_const_v<C>,
IteratorRange<typename C::const_iterator>,
IteratorRange<typename C::iterator>
>;
static range_type iter(C &r) {
return range_type{r.begin(), r.end()};
}
};
}
} /* namespace ostd */
#endif

View File

@ -13,26 +13,6 @@
namespace ostd {
template<typename K, typename T, typename H, typename E, typename A>
struct ranged_traits<std::unordered_map<K, T, H, E, A>> {
using Range = IteratorRange<
typename std::unordered_map<K, T, H, E, A>::iterator
>;
static Range iter(std::unordered_map<K, T, H, E, A> &v) {
return Range{v.begin(), v.end()};
}
};
template<typename K, typename T, typename H, typename E, typename A>
struct ranged_traits<std::unordered_map<K, T, H, E, A> const> {
using Range = IteratorRange<
typename std::unordered_map<K, T, H, E, A>::const_iterator
>;
static Range iter(std::unordered_map<K, T, H, E, A> const &v) {
return Range{v.cbegin(), v.cend()};
}
};
namespace detail {
template<typename T>
std::integral_constant<

View File

@ -14,20 +14,6 @@
namespace ostd {
template<typename T, typename A>
struct ranged_traits<std::vector<T, A>> {
static IteratorRange<T *> iter(std::vector<T, A> &v) {
return IteratorRange<T *>{v.data(), v.data() + v.size()};
}
};
template<typename T, typename A>
struct ranged_traits<std::vector<T, A> const> {
static IteratorRange<T const *> iter(std::vector<T, A> const &v) {
return IteratorRange<T const *>{v.data(), v.data() + v.size()};
}
};
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};