今更蒸し返してどうするんだって感じですが、
[C++] ピンポン
で書いた値が往復するクラス。作ってあったけどblogに書くのを忘れていたので。
#include <iostream>
using namespace std;
template<int first, int last> struct ping_pong_value {
private:
template<bool b> struct bool_ {};
static const bool has_range = first != last;
static const bool cond = first < last;
static const int low = cond ? first : last;
static const int range = cond ? last - first : first - last;
int v;
int getter(bool_<true>) const { return abs(v / range * range - (v % range)) + low; }
int getter(bool_<false>) const { return low; }
void adder(bool_<true>, int r) {
v = (v + ((r < 0) ? ((range * 2) - (abs(r) % (range * 2))) : r)) % (range * 2);
}
void adder(bool_<false>, int r) const {}
int get() const { return getter(bool_<has_range>()); }
void add(int r = 1) { adder(bool_<has_range>(), r); }
void sub(int r = 1) { adder(bool_<has_range>(), -r); }
public:
ping_pong_value(int b = low) : v(cond ? b - low : range * 2 - (b - low)) {}
int operator ++() { return (add(), get()); }
int operator ++(int) { int t = get(); return (add(), t); }
int operator +=(int r) { return (add(r), get()); }
int operator --() { return (sub(), get()); }
int operator --(int) { int t = get(); return (sub(), t); }
int operator -=(int r) { return (sub(r), get()); }
operator int() const { return get(); }
};
template<typename T> void print_value(int begin = T::low, int step = 1) {
T v(begin);
for(int i = 0; i < 20; ++i, v += step) cout << v << ", "; cout << endl;
}
int main()
{
print_value<ping_pong_value<1, 5> >(3);
print_value<ping_pong_value<1, 5> >(3, 3);
print_value<ping_pong_value<1, 5> >(3, -1);
print_value<ping_pong_value<1, 5> >(3, -3);
print_value<ping_pong_value<-5, -1> >(-3);
print_value<ping_pong_value<2, -3> >(0);
print_value<ping_pong_value<0, 0> >(0);
}
出力結果
3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4,
3, 4, 1, 4, 3, 2, 5, 2, 3, 4, 1, 4, 3, 2, 5, 2, 3, 4, 1, 4,
3, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2,
3, 2, 5, 2, 3, 4, 1, 4, 3, 2, 5, 2, 3, 4, 1, 4, 3, 2, 5, 2,
-3, -2, -1, -2, -3, -4, -5, -4, -3, -2, -1, -2, -3, -4, -5, -4, -3, -2, -1, -2,
0, -1, -2, -3, -2, -1, 0, 1, 2, 1, 0, -1, -2, -3, -2, -1, 0, 1, 2, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,