Here is a fairly simple and fairly complete example of a simple ADT for a generic BoundedInt.
- It uses boost / operator to avoid writing tedious (const, non-assigning) overloads.
- Implicit conversions make it compatible.
- I avoided smart optimizations (so itβs easier to adapt the code, for example, to a modular version or to a version that also has a lower bound)
- I also avoided direct template overloads for converting / working with mixed instances (e.g. compare BoundedInt with BoundedInt) for the same reason: you can probably rely on a compiler optimizing it for the same effect anyway
Notes:
- you need C ++ 0x support to allow the default value for Max to take effect (constexpr support); Not required as long as you specify Max manually
The following is a very simple demonstration.
#include <limits> #include <iostream> #include <boost/operators.hpp> template < typename Int=unsigned int, Int Max=std::numeric_limits<Int>::max()> struct BoundedInt : boost::operators<BoundedInt<Int, Max> > { BoundedInt(const Int& value) : _value(value) {} Int get() const { return std::min(Max, _value); } operator Int() const { return get(); } friend std::ostream& operator<<(std::ostream& os, const BoundedInt& bi) { return std::cout << bi.get() << " [hidden: " << bi._value << "]"; } bool operator<(const BoundedInt& x) const { return get()<x.get(); } bool operator==(const BoundedInt& x) const { return get()==x.get(); } BoundedInt& operator+=(const BoundedInt& x) { _value = get() + x.get(); return *this; } BoundedInt& operator-=(const BoundedInt& x) { _value = get() - x.get(); return *this; } BoundedInt& operator*=(const BoundedInt& x) { _value = get() * x.get(); return *this; } BoundedInt& operator/=(const BoundedInt& x) { _value = get() / x.get(); return *this; } BoundedInt& operator%=(const BoundedInt& x) { _value = get() % x.get(); return *this; } BoundedInt& operator|=(const BoundedInt& x) { _value = get() | x.get(); return *this; } BoundedInt& operator&=(const BoundedInt& x) { _value = get() & x.get(); return *this; } BoundedInt& operator^=(const BoundedInt& x) { _value = get() ^ x.get(); return *this; } BoundedInt& operator++() { _value = get()+1; return *this; } BoundedInt& operator--() { _value = get()-1; return *this; } private: Int _value; };
Sample Usage:
typedef BoundedInt<unsigned int, 100> max100; int main() { max100 i = 1; std::cout << (i *= 10) << std::endl; std::cout << (i *= 6 ) << std::endl; std::cout << (i *= 2 ) << std::endl; std::cout << (i -= 40) << std::endl; std::cout << (i += 1 ) << std::endl; }
Demo output:
10 [hidden: 10] 60 [hidden: 60] 100 [hidden: 120] 60 [hidden: 60] 61 [hidden: 61]
Bonus Material:
With a fully compatible C ++ 11 compiler, you can even define a Userdefined Literal transformation:
typedef BoundedInt<unsigned int, 100> max100; static max100 operator ""_b(unsigned int i) { return max100(unsigned int i); }
So you can write
max100 x = 123_b; // 100 int y = 2_b*60 - 30; // 70
sehe source share