範囲つきintのガワを適当に書いてみた結果
template<int Min, int Max> struct ranged_int { ranged_int() = default; ranged_int(ranged_int const &) = default; template<int N, typename = enable_if<(N >= Min) && (N < Max)>::type> ranged_int(integral_type<int, N>) : n_(N) {}; template<int Min1, int Max1, typename = enable_if<(Min1 >= Min) && (Max1 <= Max)>::type> ranged_int(ranged_int<Min1, Max1> const & other) : n_(other.n) {} ... template<typename Min1, typename Max2> ranged_int<Min + Min1, Max + Max1> operator+(ranged_int<Min1, Max1> && other) { return ranged_int<Min + Min1, Max + Max1>(get() + other.get()); } int get() const { return n_; } private: explicit ranged_int(int n) : n(n_) {} int n_; ... }; template<char ...ch> integral_type<int, /* chから整数作る */> operator ""_i(); ranged_int<0, 100> i = 101_i; // error
int を引数に取るコンストラクタは定義したいんだけど、その前にその変数が本当に[Min, Max)に収まっているかどうかを証明してほしいなぁ…コンパイル時に。現実的にいくならmake_ranged_int<M, N>(int n)みたいな関数で[M, N)かチェックして違っていれば例外、とか。
代入も定義できんなぁ…ranged_int<M, N> x = integral_type<int, M>(); ranged_int<K, L> y = integral_type<int, K>();でx = y;とかやったあとのdecltype(x)の結果はranged_int<K, L>になって欲しいし…まぁ代入とかなくてもいいよね。
あとはもっと型テンプレートの引数に条件とか埋めこみまくれるようにしていく必要がある…