$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r64183 - sandbox/opaque/boost/opaque
From: vicente.botet_at_[hidden]
Date: 2010-07-19 18:10:32
Author: viboes
Date: 2010-07-19 18:10:31 EDT (Mon, 19 Jul 2010)
New Revision: 64183
URL: http://svn.boost.org/trac/boost/changeset/64183
Log:
conversion between public typedefs is transitive now.
Text files modified: 
   sandbox/opaque/boost/opaque/opaque.hpp |   169 +++++++++++++++++++++++++++------------ 
   1 files changed, 115 insertions(+), 54 deletions(-)
Modified: sandbox/opaque/boost/opaque/opaque.hpp
==============================================================================
--- sandbox/opaque/boost/opaque/opaque.hpp	(original)
+++ sandbox/opaque/boost/opaque/opaque.hpp	2010-07-19 18:10:31 EDT (Mon, 19 Jul 2010)
@@ -37,21 +37,77 @@
     BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
     
 namespace boost {
-
+       
     class base_public_opaque_type {};
     class base_private_opaque_type {};
-        
-#if 0
-    template <typename T, typename Subst, typename Base>
+   
+    template <typename UT, typename Base>
+    struct basic_conv : Base {
+        typedef Base base_type;
+        basic_conv() {}
+        basic_conv(UT val) : base_type(val) {}
+            
+        // public specific conversions
+        operator UT () const {
+            return this->val_;
+        }
+        //~ operator UT & () {
+            //~ return this->val_;
+        //~ }
+    };
+
+
+    template <typename T, typename UT, bool B, typename Base>
+    struct conv_public_opaque_type2;
+
+    template <typename T, typename UT, typename Base>
+    struct conv_public_opaque_type2<T, UT,true,Base> :  public UT::template conv<T, Base>::type
+    {
+        typedef typename UT::template conv<T, Base>::type base_type;
+        conv_public_opaque_type2() {} 
+        conv_public_opaque_type2(T val) : base_type(val) {}
+            
+    };
+    template <typename T, typename UT, typename Base>
+    struct conv_public_opaque_type2<T, UT, false, Base> :  public basic_conv<T, Base>
+    {
+        typedef basic_conv<T, Base> base_type;
+        conv_public_opaque_type2() {} 
+        conv_public_opaque_type2(T val) : base_type(val) {}
+            
+    };
+    
+    template <typename T, typename UT, bool B, typename Base>
     struct conv_public_opaque_type;
 
-    template <typename T, typename Base>
-    struct conv_public_opaque_type<T,void: public Base;
+    template <typename T, typename UT, typename Base>
+    struct conv_public_opaque_type<T, UT,true,Base> :  public UT::template conv<T, Base>::type
     {
-    protected:
-        T val_;
+        typedef typename UT::template conv<T, Base>::type base_type;
+        conv_public_opaque_type() {} 
+        conv_public_opaque_type(T val) : base_type(val) {}
+            
+        // public specific conversions
+        operator UT () const {
+            //~ return UT(this->val_);
+            return this->val_.operator UT();
+        }
     };
-#endif        
+    template <typename T, typename UT, typename Base>
+    struct conv_public_opaque_type<T, UT, false, Base> :  public basic_conv<T, Base>
+    {
+        typedef basic_conv<T, Base> base_type;
+        conv_public_opaque_type() {} 
+        conv_public_opaque_type(T val) : base_type(val) {}
+            
+        // public specific conversions
+        operator UT () const {
+            //~ return UT(this->val_);
+            return this->val_.operator UT();
+        }
+    };
+    
+        
     template <typename T, bool B>
     struct get_substituables;
 
@@ -67,30 +123,29 @@
         //~ typedef mpl::single_view<T> type; 
     };
 
-    template <typename Final, typename T, typename Base=base_private_opaque_type>
+    template <typename Final, typename T, typename Base>
     class opaque_type
-        : boost::totally_ordered< Final
-          , boost::integer_arithmetic< Final
-            , boost::bitwise< Final
-              , boost::unit_steppable< Final
-                , Base
+        : public boost::totally_ordered< Final
+            , boost::integer_arithmetic< Final
+              , boost::bitwise< Final
+                , boost::unit_steppable< Final
+                  , Base
+                >
               >
             >
           >
-        >
+        
     {
-    protected:
-        T val_;
     public:
         typedef T underlying_type;
         typedef typename get_substituables<T,
                 mpl::and_<is_class<T>, is_base_of<base_public_opaque_type,T> >::value 
                  >::type substituables;
     
-        template <typename W>
-        explicit opaque_type(const W v, enable_if<mpl::contains<substituables,W> >*dummy =0)
-            : val_(v)
-        {}
+        //~ template <typename W>
+        //~ explicit opaque_type(const W v, enable_if<mpl::contains<substituables,W> >*dummy =0)
+            //~ : val_(v)
+        //~ {}
 
         opaque_type()
         {}
@@ -98,20 +153,15 @@
         opaque_type(const opaque_type & rhs)
             : val_(rhs.val_)
         {}
+        explicit opaque_type(T v)
+            : val_(v)
+        {}
     protected:            
+        T val_;
         opaque_type & operator=(const opaque_type & rhs) {
             val_ = rhs.val_; return *this;
         }
-        //~ opaque_type & operator=(const T rhs) {
-            //~ val_ = rhs; return *this;
-        //~ }
 
-        template <typename W>
-        typename enable_if<mpl::contains<substituables,W>, opaque_type &>::type
-        operator=(const W rhs) {
-            val_ = rhs;
-            return *this;
-        }
     public:            
         T const& underlying() const {
             return val_;
@@ -153,46 +203,56 @@
 
     template <typename Final, typename T>
     class public_opaque_type
-        : public opaque_type< Final, T, base_public_opaque_type>
+        : public 
+            conv_public_opaque_type2<T, T, mpl::and_<is_class<T>, is_base_of<base_public_opaque_type,T> >::value,
+                opaque_type< Final, T, base_public_opaque_type> 
+            >
     {
+        typedef 
+            conv_public_opaque_type2<T, T, mpl::and_<is_class<T>, is_base_of<base_public_opaque_type,T> >::value,
+                opaque_type< Final, T, base_public_opaque_type> 
+            > base_type;
+
     protected:
         typedef public_opaque_type opaque_type_t;
     public:
         typedef T underlying_type;
         typedef typename opaque_type< Final, T, base_public_opaque_type>::substituables substituables; 
+        template <typename U, typename B> 
+        struct conv {
+            typedef 
+                conv_public_opaque_type<U, T,
+                    mpl::and_<is_class<T>, is_base_of<base_public_opaque_type,T> >::value, 
+                    B> type;
+        };
         //~ Can instances of UT be explicitly converted to instances of OT?
         //~ Proposed answer: yes.
         //~ Can instances of UT be implicitly converted to instances of OT?
         //~ Proposed answer: no.
 
-        template <typename W>
-        explicit public_opaque_type(const W v, enable_if<mpl::contains<substituables,W> >*dummy =0)
-            : opaque_type< Final, T, base_public_opaque_type>(v)
-        {}
+        public_opaque_type() {} 
 
-        public_opaque_type()
+        public_opaque_type(const opaque_type_t & rhs)
+            : base_type(rhs.val_)
         {}
 
-        public_opaque_type(const opaque_type_t & rhs)
-            : opaque_type< Final, T, base_public_opaque_type>(rhs.val_)
+        explicit public_opaque_type(const T v)
+            : base_type(v)
         {}
+        //~ template <typename W>
+        //~ explicit public_opaque_type(const W v, enable_if<mpl::contains<substituables,W> >*dummy =0)
+            //~ : base_type(v)
+        //~ {}
+            
         public_opaque_type & operator=(const opaque_type_t & rhs) {
             this->val_ = rhs.val_; return *this;
         }
-        
-        //~ template <typename W>
-        //~ typename enable_if<mpl::contains<substituables,W>, public_opaque_type &>::type
-        //~ operator=(const W rhs) {
-            //~ this->operator=(rhs);
-            //~ return *this;
-        //~ }
-
 
         // public specific conversions
-        operator const T & () const {
+        operator T() const {
             return this->val_;
         }
-        operator T & () {
+        operator T() {
             return this->val_;
         }
         
@@ -209,8 +269,9 @@
 
     template <typename Final, typename T>
     class private_opaque_type
-        : public opaque_type< Final, T, base_private_opaque_type>
+        : public opaque_type< Final, T, base_private_opaque_type >
     {
+        typedef opaque_type< Final, T, base_private_opaque_type > base_type;        
     protected:
         typedef private_opaque_type opaque_type_t;
     public:
@@ -220,14 +281,14 @@
         //~ Can instances of UT be implicitly converted to instances of OT?
         //~ Proposed answer: no.
 
-        explicit private_opaque_type(const T v)
-            : opaque_type< Final, T, base_private_opaque_type>(v)
-        {};
         private_opaque_type()
         {};
         private_opaque_type(const opaque_type_t & rhs)
-            : opaque_type< Final, T, base_private_opaque_type>(rhs.val_)
+            : base_type(rhs.val_)
         {}
+        explicit private_opaque_type(const T v)
+            : base_type(v)
+        {};
         //~ private_opaque_type & operator=(const opaque_type_t & rhs) {
             //~ val_ = rhs.val_; return *this;
         //~ }