1#pragma once
2
3#include <type_traits>
4#include <boost/range/counting_range.hpp>
5#include <boost/range/adaptor/transformed.hpp>
6
7
8namespace 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