Listing 2

#include "constrained_value.hpp"
#include <iostream>

typedef cv::constrained_value 
      < cv::policies::ranged_integer < 0, 59 > > Base60_A;
typedef cv::constrained_value 
      < cv::policies::ranged_integer < 0, 59, 
        cv::policies::saturating > > Base60_B;

template < int max_T >
struct modulo_integer_constraints {
  typedef int value;
  static void assign(const value& rvalue, value& lvalue) {
    lvalue = rvalue % max_T;
  }
};
typedef cv::constrained_value < modulo_integer_constraints < 60 > > Base60_C;

struct non_negative_double_constraint {
  typedef double value;
  static void assign(const value& rvalue, value& lvalue) {
    if (rvalue < 0.0) { throw 0; }
    lvalue = rvalue;
  }
};
typedef cv::constrained_value 
        < non_negative_double_constraint > non_negative_double;
int main()
{  
  Base60_A a = 10;
  a = a + 20; 
  try {
    std::cout << "exception should be thrown" << std::endl;
    a = a + 40; 
    std::cout << "no exception thrown" << std::endl;
  }
  catch(...) {
    std::cout << "exception caught" << std::endl;
  }
  Base60_B b = 10; 
  std::cout << "Output should be 10" << std::endl << b << std::endl; 
  b = b + 70;
  std::cout << "Output should be 59" << std::endl << b << std::endl; 
  Base60_C c = 10;
  std::cout << "Output should be 10" << std::endl << c << std::endl; 
  c = c + 70;
  std::cout << "Output should be 20" << std::endl << c << std::endl; 
  non_negative_double d(1.0);
  try {
    std::cout << "exception should be thrown" << std::endl;
    d = -1.0;
    std::cout << "no exception thrown" << std::endl;
  }
  catch(...) {
    std::cout << "exception caught" << std::endl;
  }
  std::cin.get();
  return 0;
};