Interessant (nicht zwingend hübsch) finde ich auch den alternativen From().To()-Syntax. Und Sry, ich weiß, dass Syntax weiblich ist, ist es in meinem Kopf aber nicht. Bei mir ist immer "der Syntax". Geht das anderen auch so?
Code: Alles auswählen
#include <type_traits>
template <typename T> class value_range
{
public:
struct iterator
{
T value;
const T step;
constexpr iterator (T _value, T _step = T(1)) : value(_value), step(_step) {}
constexpr operator T () const { return value; }
constexpr operator T& () { return value; }
constexpr T operator* () const { return value; }
constexpr iterator& operator++ () { value += step; return *this; }
constexpr bool operator != (const iterator& other) const {return (step>0) ? value < other.value : value > other.value;}
};
constexpr value_range(const T _end): i_begin(T(0)), i_end(_end) {}
constexpr value_range(const auto _start, const auto _end): i_begin(_start), i_end(_end) {}
constexpr value_range(const auto _start, const auto _end, const auto _step): i_begin(_start, _step), i_end(_end, _step) {}
constexpr const iterator& begin() const { return i_begin; }
constexpr const iterator& end() const { return i_end; }
using value_type = T;
private:
const iterator i_begin;
const iterator i_end;
};
template<typename T1, typename T2> value_range(T1, T2) -> value_range<std::common_type_t<T1, T2>>;
template<typename T1, typename T2, typename T3> value_range(T1, T2, T3) -> value_range<std::common_type_t<T1, T2>>;
//=================================================================================================================================
template<typename T>struct To
{
const value_range<T> i;
To(T end) : i(end) {};
constexpr const typename value_range<T>::iterator& begin() const { return i.begin(); }
constexpr const typename value_range<T>::iterator& end() const { return i.end(); }
};
template<typename T> auto From(const T start)
{
struct ProvideTo
{
const T start;
constexpr ProvideTo(const T _start): start(_start) {}
constexpr auto To(T _end) const
{
struct ProvideStep
{
const value_range<T> i;
constexpr ProvideStep(T _start, T _end): i(_start, _end) {};
constexpr const typename value_range<T>::iterator& begin() const { return i.begin(); }
constexpr const typename value_range<T>::iterator& end() const { return i.end(); }
constexpr auto Step(T _step)
{
return value_range{*i.begin(), *i.end(), _step};
}
};
return ProvideStep{start, _end};
}
};
return ProvideTo{start};
};
//=================================================================================================================================
#include <numeric>
int square(int num)
{
int sum = 0;
for(auto i : To(5)) sum += i; //0+1+2+3+4 = 10
for(auto i : From(1).To(5)) sum += i; //1+2+3+4 = 10
for(auto i : From(1).To(5).Step(2)) sum += i; //1+3 = 4
for(auto i : value_range(5)) sum += i; //0+1+2+3+4 = 10
for(auto i : value_range{3, 5u}) sum += i; //3+4 = 7
for(auto i : value_range{3, 6u, 2.0}) sum += i; // 3+5 = 8
// 49
auto range = value_range(1.0f, 10.0f, 1);
auto fsum = std::accumulate(range.begin(), range.end(), 0.0);
asm volatile ("":"=m"(fsum):"m"(fsum));
return sum;
}
//Höhö Highlighting kaputt:
constexpr
operator
override
final
asm
Hier https://godbolt.org/g/3BF2SP
kA, nix Wildes, aber irgendwie finde ich es teilungswürdig. Vielleicht gibts ja Kommentare :-)