/*

File: test_embed_type.hpp
Author: David Bergman
Date: 2006-07-25

This is a simple test of the 'embed_type' proposal, which is
actually just a slightly decoupled (policy-wise) and more generic
version of Beman Daves' "identifier" proposal.

*/

#include <iostream>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/remove.hpp>

#include <boost/embed_type.hpp>

// We include Beman Daves' identifier here as a special case.
// Here, only the order and equivalence are preserved from the raw type.

namespace boost {
  template<typename T, typename D>
  class identifier :
    public embed_type<T, D,
		      mpl::vector<policy<embed_order>,
				  policy<embed_equivalence> > > {};
} // namespace boost


// Create a customer Id type which is *almost* isomorphic to int,
// except for conversion to int

typedef boost::mpl::remove<boost::embed_policy_all,
			   boost::policy<boost::embed_conversion> >::type
policy_no_convert;

class CustomerId : public boost::embed_type<int, CustomerId, policy_no_convert>
{
public:
  CustomerId() {}
  // Ugh, GCC does not support mentioning only the template
  // name for sub classes :-(
  CustomerId(int num) : boost::embed_type<int, CustomerId, policy_no_convert>(num) {}
};

int main(int argc, const char* argv[])
{
  CustomerId id = 42;
  id += 2; // works thanks to the inclusion of embed_arithmetics
  int idNum = static_cast<int>(id); // only works if you add the embed_conversion polocy
  std::cout << "Id is CustomerId(" << idNum << ")" <<
    std::endl;
}

