1 | #pragma once |
2 | |
3 | #include <type_traits> |
4 | #include <boost/range/counting_range.hpp> |
5 | #include <boost/range/adaptor/transformed.hpp> |
6 | |
7 | |
8 | namespace ext |
9 | { |
10 | /// For loop adaptor which is used to iterate through a half-closed interval [begin, end). |
11 | template <typename BeginType, typename EndType> |
12 | inline auto range(BeginType begin, EndType end) |
13 | { |
14 | using CommonType = typename std::common_type<BeginType, EndType>::type; |
15 | return boost::counting_range<CommonType>(begin, end); |
16 | } |
17 | |
18 | template <typename Type> |
19 | inline auto range(Type end) |
20 | { |
21 | return range<Type, Type>(static_cast<Type>(0), end); |
22 | } |
23 | |
24 | /// The same as range(), but every value is casted statically to a specified `ValueType`. |
25 | /// This is useful to iterate through all constants of a enum. |
26 | template <typename ValueType, typename BeginType, typename EndType> |
27 | inline auto range_with_static_cast(BeginType begin, EndType end) |
28 | { |
29 | using CommonType = typename std::common_type<BeginType, EndType>::type; |
30 | if constexpr (std::is_same_v<ValueType, CommonType>) |
31 | return boost::counting_range<CommonType>(begin, end); |
32 | else |
33 | return boost::counting_range<CommonType>(begin, end) |
34 | | boost::adaptors::transformed([](CommonType x) -> ValueType { return static_cast<ValueType>(x); }); |
35 | } |
36 | |
37 | template <typename ValueType, typename EndType> |
38 | inline auto range_with_static_cast(EndType end) |
39 | { |
40 | return range_with_static_cast<ValueType, EndType, EndType>(static_cast<EndType>(0), end); |
41 | } |
42 | } |
43 | |