#ifndef PFOR_PFOR_RANGE_H #define PFOR_PFOR_RANGE_H #include #include "index/index.h" namespace pfor { /** * @brief a dynamic range holder * * Actual class for dynamic ranges */ template 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 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 class TRangeCT { public: using ValueType = T; private: ValueType _end; public: TRangeCT(ValueType end): _end{end} {} constexpr auto begin() const { return TRangeCTValue{}; } ValueType end() const { return _end; } constexpr auto step() const { return TRangeCTValue{}; } }; /** * @brief Dynamic range (begin, end, step) */ using Range = TRange; /** * @brief Static-(begin, step), dynamic-(end) range */ template using RangeCT = TRangeCT; /** * @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 auto makeRange(T&& begin, T&& end, T&& step) { return TRange>{std::forward(begin), std::forward(end), std::forward(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 auto makeRange(TRangeCTValue, begin>, T&& end, TRangeCTValue, step>) { return TRangeCT, begin, step>{std::forward(end)}; } } #endif