//Purpose:
//  See if one_of_maybe can handle code posted here:
//
/*
http://lists.boost.org/Archives/boost/2010/02/162167.php
 */
#include <boost/composite_tagged_seq.hpp>
#include <boost/mpl/list.hpp>

#include <memory>
#include <vector>

struct empty {};
struct foo {};
struct bar {};
typedef std::unique_ptr<foo> foo_ptr;
typedef std::unique_ptr<bar> bar_ptr;

typedef std::vector<foo_ptr> foo_ptr_vec;
typedef std::vector<bar_ptr> bar_ptr_vec;

    typedef 
  boost::composite_tagged_seq
  < boost::composite_tags::one_of_maybe
  , boost::mpl::integral_c<int,0>
  , boost::mpl::list
    < empty
    , foo_ptr_vec
    , bar_ptr_vec
    > 
  >
my_variant;

class my_class
: public my_variant
{
    my_class(const my_class&);
    my_class& operator=(const my_class&); 

public:
    my_class()
        : my_variant(boost::mpl::integral_c<int,0>(), empty())
    {
    } 
    my_class(my_class&& other)
        : my_variant(std::move(other))
    {
    }
};
#include <iostream>
int main(void)
{
    my_class x;
    std::cout<<"***after my_class  default::CTOR:\n";
    std::cout<<"   which="<<x.which()<<"\n";
    foo_ptr fp(new foo);
    std::cout<<"***after foo_ptr::CTOR:\n";
    std::cout<<"  fp.get="<<fp.get()<<"\n";
    foo_ptr_vec fpv1;
    fpv1.push_back(std::move(fp));
    std::cout<<"***after push:\n";
    std::cout<<"  fp.get="<<fp.get()<<"\n";
    std::cout<<"  fpv1.at(0).get()="<<fpv1.at(0).get()<<"\n";
    foo_ptr_vec fpv2(std::move(fpv1));
    std::cout<<"***after vec move:\n";
    std::cout<<"  fpv1.size()="<<fpv1.size()<<"\n";
    std::cout<<"  fpv2.at(0).get()="<<fpv2.at(0).get()<<"\n";
    x.inject<1>(std::move(fpv2));
    std::cout<<"***after inject:\n";
    std::cout<<"  foo_ptr_vec which="<<x.which()<<"\n";
    std::cout<<"  fpv2.size()="<<fpv2.size()<<"\n";
    std::cout<<"  x.project<1>()->at(0).get()="<<x.project<1>()->at(0).get()<<"\n";
    return 0;
}      

