Spielerei mit Integer-Range-based for loop
Verfasst: 19.04.2018, 09:10
Gibts sicher schon oft, aber war auch nur ein kleiner Test damit man in C++17 fitter bleibt.
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?Ob das constexpr überall sein muss.. kA.
Hier https://godbolt.org/g/3BF2SP
kA, nix Wildes, aber irgendwie finde ich es teilungswürdig. Vielleicht gibts ja Kommentare :-)
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 :-)