pfor/src/pfor/range.h

106 lines
2.3 KiB
C++

#ifndef PFOR_PFOR_RANGE_H
#define PFOR_PFOR_RANGE_H
#include <utility>
#include "index/index.h"
namespace pfor {
/**
* @brief a dynamic range holder
*
* Actual class for dynamic ranges
*/
template<typename T>
class TRange {
public:
using ValueType = T;
private:
ValueType _begin;
ValueType _end;
ValueType _step;
public:
TRange(ValueType begin, ValueType end, ValueType step = 1):
_begin{begin}, _end{end}, _step{step}
{}
ValueType begin() const { return _begin; }
ValueType end() const { return _end; }
ValueType step() const { return _step; }
};
/**
* @brief a compile time value holder for TRangeCT
*/
template<typename T, T _value>
struct TRangeCTValue {
constexpr operator T() const { return _value; }
};
/**
* @brief a static-(begin, step) and dynamic-(end) range holder
*
* Actual class for static-(begin, step) and dynamic-(end) range
*/
template<typename T, T _begin, T _step>
class TRangeCT {
public:
using ValueType = T;
private:
ValueType _end;
public:
TRangeCT(ValueType end): _end{end} {}
constexpr auto begin() const { return TRangeCTValue<T, _begin>{}; }
ValueType end() const { return _end; }
constexpr auto step() const { return TRangeCTValue<T, _step>{}; }
};
/**
* @brief Dynamic range (begin, end, step)
*/
using Range = TRange<index::Value>;
/**
* @brief Static-(begin, step), dynamic-(end) range
*/
template<index::Value begin, index::Value step>
using RangeCT = TRangeCT<index::Value, begin, step>;
/**
* @brief helper to create a dynamic range
*
* @param[in] begin initial value
* @param[in] end post-last value
* @param[in] step incremental step
*
* @return a dynamic range
*/
template<typename T>
auto makeRange(T&& begin, T&& end, T&& step) {
return TRange<std::decay_t<T>>{std::forward<T>(begin), std::forward<T>(end), std::forward<T>(step)};
}
/**
* @brief helper to create a static-(begin, step) and dynamic-(end) range
*
* @param[in] begin statically known initial value
* @param[in] step statically known incremental step
* @param[in] end post-last value
*
* @return a range with (begin, step) known at compile-time
*/
template<typename T, index::Value begin, index::Value step>
auto makeRange(TRangeCTValue<std::decay_t<T>, begin>, T&& end, TRangeCTValue<std::decay_t<T>, step>) {
return TRangeCT<std::decay_t<T>, begin, step>{std::forward<T>(end)};
}
}
#endif