1 // Copyright (C) 2018 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
12 #include "util/assert.hpp"
13 #include "util/type_traits.hpp"
20 struct RangeIncrementer
22 template<typename Rng>
23 void operator()(Rng& range) const
32 template<typename Rng>
33 void operator()(Rng& range)
35 empty = empty || range.empty();
40 template<typename Rng>
41 void operator()(Rng& range) const
47 //SFINAE and decltype doesn't work wery well together
48 // so this additional wrapper is needed
50 struct range_size_wrapper_helper
52 using type = decltype(size(std::declval<T>()));
56 inline auto range_size_wrapper(const T& r)
57 ->typename range_size_wrapper_helper<T>::type
69 static y test(decltype(size(std::declval<C>()))*);
73 static const constexpr bool value = (sizeof(test<T>(0)) == sizeof(y));
77 inline namespace Range
79 template<typename BeginT, typename EndT = BeginT>
97 return beginIter == endIter;
106 auto front() -> decltype(*beginIter)
112 auto front() const -> decltype(*beginIter)
118 bool operator==(const IterRange<BeginT, EndT>& rhs) const
120 return beginIter == rhs.beginIter && endIter == rhs.endIter;
123 bool operator!=(const IterRange<BeginT, EndT>& rhs) const
125 return !(*this == rhs);
128 template<typename I1 = BeginT, typename I2 = EndT,
129 util::enable_b_t<(sizeof(std::declval<I2>() - std::declval<I1>()) > 0)> = true> //SFINAE
131 ->decltype(std::declval<I2>() - std::declval<I1>())
133 return endIter - beginIter;
136 // TODO: bidirectional and random access ranges
139 template<typename BeginT, typename EndT>
140 inline auto size(const IterRange<BeginT, EndT>& range)
141 ->decltype(range.size())
147 inline auto toRange(T&& val) -> IterRange<decltype(std::begin(val)), decltype(std::end(val))>
149 return {std::begin(val), std::end(val)};
153 inline auto toRangeReverse(T&& val) -> IterRange<decltype(val.rbegin()), decltype(val.rbegin())>
155 // TODO: use c++14 std::rbegin, std::rend
156 return {val.rbegin(), val.rend()};
159 template<typename Iter>
160 inline auto toRange(const std::pair<Iter,Iter>& val) -> IterRange<decltype(val.first), decltype(val.second)>
162 return {val.first, val.second};
165 template<typename Iter>
166 inline auto toRange(Iter&& val, std::size_t count) -> IterRange<remove_reference_t<Iter>, remove_reference_t<Iter>>
168 return {std::forward<Iter>(val), std::next(val, count)};
172 inline auto index(T&& val)->decltype(std::get<0>(std::forward<T>(val)))
174 return std::get<0>(std::forward<T>(val));
177 template<int I = 0, typename T>
178 inline auto value(T&& val)->decltype(std::get<I + 1>(std::forward<T>(val)))
180 static_assert(I >= 0,"Invalid I");
181 return std::get<I + 1>(std::forward<T>(val));
184 template<typename Range>
185 inline void advance_range(Range&& range)
193 #endif // UTIL_RANGE_HPP