$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80910 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/example
From: steven_at_[hidden]
Date: 2012-10-08 19:37:01
Author: steven_watanabe
Date: 2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
New Revision: 80910
URL: http://svn.boost.org/trac/boost/changeset/80910
Log:
Allow mutating functions to be called on const any<C, P&>.
Added:
   sandbox/type_erasure/boost/type_erasure/detail/const.hpp   (contents, props changed)
Text files modified: 
   sandbox/type_erasure/boost/type_erasure/call.hpp              |    14 +++++++++                               
   sandbox/type_erasure/boost/type_erasure/detail/access.hpp     |    12 +++++++                                 
   sandbox/type_erasure/boost/type_erasure/free.hpp              |     3 +                                       
   sandbox/type_erasure/boost/type_erasure/member.hpp            |    38 +++++++++++++++++++-----                
   sandbox/type_erasure/boost/type_erasure/operators.hpp         |    62 +++++++++++++++++++++++++++++++++------ 
   sandbox/type_erasure/libs/type_erasure/example/references.cpp |    19 ------------                            
   6 files changed, 110 insertions(+), 38 deletions(-)
Modified: sandbox/type_erasure/boost/type_erasure/call.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/call.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/call.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -92,6 +92,20 @@
 
 template<class Concept, class T>
 ::boost::type_erasure::detail::storage&
+convert_arg(const any_base<any<Concept, T&> >& arg, boost::mpl::true_)
+{
+    return ::boost::type_erasure::detail::access::data(arg);
+}
+
+template<class Concept, class T>
+const ::boost::type_erasure::detail::storage&
+convert_arg(const any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
+{
+    return ::boost::type_erasure::detail::access::data(arg);
+}
+
+template<class Concept, class T>
+::boost::type_erasure::detail::storage&
 convert_arg(param<Concept, T>& arg, boost::mpl::true_)
 {
     return ::boost::type_erasure::detail::access::data(arg);
Modified: sandbox/type_erasure/boost/type_erasure/detail/access.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/access.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/detail/access.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -59,6 +59,18 @@
     }
     template<class Concept, class T>
     static ::boost::type_erasure::detail::storage&
+    data(const ::boost::type_erasure::any_base< ::boost::type_erasure::any<Concept, T&> >& arg)
+    {
+        return const_cast< ::boost::type_erasure::detail::storage&>(static_cast< const ::boost::type_erasure::any<Concept, T&>&>(arg).data);
+    }
+    template<class Concept, class T>
+    static const ::boost::type_erasure::detail::storage&
+    data(const ::boost::type_erasure::any_base< ::boost::type_erasure::any<Concept, const T&> >& arg)
+    {
+        return static_cast<const ::boost::type_erasure::any<Concept, const T&>&>(arg).data;
+    }
+    template<class Concept, class T>
+    static ::boost::type_erasure::detail::storage&
     data(::boost::type_erasure::param<Concept, T>& arg)
     {
         return arg._impl.data;
Added: sandbox/type_erasure/boost/type_erasure/detail/const.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/const.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -0,0 +1,97 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_erasure/placeholder_of.hpp>
+#include <boost/type_erasure/derived.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class T>
+struct is_non_const_ref : boost::mpl::false_ {};
+template<class T>
+struct is_non_const_ref<T&> : boost::mpl::true_ {};
+template<class T>
+struct is_non_const_ref<const T&> : boost::mpl::false_ {};
+
+template<class Placeholder, class Base>
+struct should_be_const :
+    ::boost::mpl::or_<
+        ::boost::is_const<Placeholder>,
+        ::boost::type_erasure::detail::is_non_const_ref<
+            typename ::boost::type_erasure::placeholder_of<Base>::type
+        >
+    >
+{};
+
+template<class Placeholder, class Base>
+struct should_be_non_const :
+    ::boost::mpl::and_<
+        ::boost::mpl::not_< ::boost::is_const<Placeholder> >,
+        ::boost::mpl::not_<
+            ::boost::is_reference<
+                typename ::boost::type_erasure::placeholder_of<Base>::type
+            >
+        >
+    >
+{};
+
+template<class Base>
+struct non_const_this_param
+{
+    typedef typename ::boost::type_erasure::placeholder_of<Base>::type placeholder;
+    typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
+    typedef typename ::boost::mpl::if_<
+        ::boost::is_same<
+            placeholder,
+            typename ::boost::remove_cv<
+                typename ::boost::remove_reference<placeholder>::type
+            >::type&
+        >,
+        const plain_type,
+        plain_type
+    >::type type;
+};
+
+template<class T>
+struct uncallable {};
+
+template<class Placeholder, class Base>
+struct maybe_const_this_param
+{
+    typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
+    typedef typename ::boost::mpl::if_<
+        ::boost::type_erasure::detail::should_be_non_const<Placeholder, Base>,
+        plain_type&,
+        typename ::boost::mpl::if_<
+            ::boost::type_erasure::detail::should_be_const<Placeholder, Base>,
+            const plain_type&,
+            uncallable<plain_type>
+        >::type
+    >::type type;
+};
+
+}
+}
+}
+
+#endif
Modified: sandbox/type_erasure/boost/type_erasure/free.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/free.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/free.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -24,6 +24,7 @@
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/next.hpp>
 #include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/detail/const.hpp>
 #include <boost/type_erasure/config.hpp>
 #include <boost/type_erasure/derived.hpp>
 #include <boost/type_erasure/rebind_any.hpp>
@@ -70,7 +71,7 @@
 /** INTERNAL ONLY */
 #define BOOST_TYPE_ERASURE_FREE_PARAM_TYPE(z, n, data)                      \
     typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
-        ::boost::type_erasure::derived<Base>,                               \
+        ::boost::type_erasure::detail::maybe_const_this_param<BOOST_PP_CAT(T, n), Base>,    \
         ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>           \
     >::type BOOST_PP_CAT(t, n)
 
Modified: sandbox/type_erasure/boost/type_erasure/member.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/member.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/member.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -21,6 +21,7 @@
 #include <boost/preprocessor/seq/size.hpp>
 #include <boost/preprocessor/seq/elem.hpp>
 #include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/detail/const.hpp>
 #include <boost/type_erasure/rebind_any.hpp>
 #include <boost/type_erasure/placeholder.hpp>
 #include <boost/type_erasure/call.hpp>
@@ -61,7 +62,13 @@
         class T, class Base, class Enable>                                                      \
     struct concept_interface<                                                                   \
         BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
-        Base, T,  Enable> : Base                                                                \
+        Base,                                                                                   \
+        typename ::boost::enable_if<                                                            \
+            ::boost::type_erasure::detail::should_be_non_const<T, Base>,                        \
+            typename ::boost::remove_const<T>::type                                             \
+        >::type,                                                                                \
+        Enable                                                                                  \
+    > : Base                                                                                    \
     {                                                                                           \
         typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member);                      \
         typename rebind_any<Base, R>::type member(                                              \
@@ -76,22 +83,33 @@
         class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A),                                      \
         class T, class Base, class Enable>                                                      \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N),                                 \
-        Base, T, Enable> : Base                                                                 \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
+        Base,                                                                                   \
+        typename ::boost::enable_if<                                                            \
+            ::boost::type_erasure::detail::should_be_const<T, Base>,                            \
+            typename ::boost::remove_const<T>::type                                             \
+        >::type,                                                                                \
+        Enable                                                                                  \
+    > : Base                                                                                    \
     {                                                                                           \
         typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member);                      \
         typename rebind_any<Base, R>::type member(                                              \
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const                           \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(),                       \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(),                         \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base>            \
     struct concept_interface<                                                                   \
         BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
-        Base, T, typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base    \
+        Base,                                                                                   \
+        typename ::boost::enable_if<                                                            \
+            ::boost::type_erasure::detail::should_be_non_const<T, Base>,                        \
+            typename ::boost::remove_const<T>::type                                             \
+        >::type,                                                                                \
+        typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base             \
     {                                                                                           \
         using Base::member;                                                                     \
         typename rebind_any<Base, R>::type member(                                              \
@@ -104,8 +122,12 @@
     };                                                                                          \
     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base>            \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N),                                 \
-        Base, T,                                                                                \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
+        Base,                                                                                   \
+        typename ::boost::enable_if<                                                            \
+            ::boost::type_erasure::detail::should_be_const<T, Base>,                            \
+            typename ::boost::remove_const<T>::type                                             \
+        >::type,                                                                                \
         typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base             \
     {                                                                                           \
         using Base::member;                                                                     \
@@ -113,7 +135,7 @@
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const                           \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(),                       \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(),                         \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
Modified: sandbox/type_erasure/boost/type_erasure/operators.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/operators.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/operators.hpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -13,6 +13,7 @@
 
 #include <iosfwd>
 #include <boost/utility/enable_if.hpp>
+#include <boost/type_erasure/detail/const.hpp>
 #include <boost/type_erasure/call.hpp>
 #include <boost/type_erasure/concept_interface.hpp>
 #include <boost/type_erasure/placeholder.hpp>
@@ -40,7 +41,11 @@
     };                                                                              \
                                                                                     \
     template<class T, class Base>                                                   \
-    struct concept_interface<name<T>, Base, T> : Base                               \
+    struct concept_interface<name<T>, Base, T,                                      \
+        typename ::boost::enable_if<                                                \
+            detail::should_be_non_const<T, Base>                                    \
+        >::type                                                                     \
+    > : Base                                                                        \
     {                                                                               \
         typedef typename ::boost::type_erasure::derived<Base>::type _derived;       \
         _derived& operator op()                                                     \
@@ -55,6 +60,28 @@
             ::boost::type_erasure::call(name<T>(), *this);                          \
             return result;                                                          \
         }                                                                           \
+    };                                                                              \
+                                                                                    \
+    template<class T, class Base>                                                   \
+    struct concept_interface<name<T>, Base, T,                                      \
+        typename ::boost::enable_if<                                                \
+            detail::should_be_const<T, Base>                                        \
+        >::type                                                                     \
+    > : Base                                                                        \
+    {                                                                               \
+        typedef typename ::boost::type_erasure::derived<Base>::type _derived;       \
+        const _derived& operator op() const                                         \
+        {                                                                           \
+            ::boost::type_erasure::call(name<T>(), *this);                          \
+            return static_cast<const _derived&>(*this);                             \
+        }                                                                           \
+        typename ::boost::type_erasure::rebind_any<Base, T>::type operator op(int) const \
+        {                                                                           \
+            typename ::boost::type_erasure::rebind_any<Base, T>::type result(       \
+                static_cast<const _derived&>(*this));                               \
+            ::boost::type_erasure::call(name<T>(), *this);                          \
+            return result;                                                          \
+        }                                                                           \
     };
 
 /**
@@ -179,10 +206,17 @@
     };                                                                      \
                                                                             \
     template<class T, class U, class Base>                                  \
-    struct concept_interface<name<T, U>, Base, T> : Base                    \
+    struct concept_interface<name<T, U>, Base, T,                           \
+        typename ::boost::disable_if<                                       \
+            ::boost::is_same<                                               \
+                typename ::boost::type_erasure::placeholder_of<Base>::type, \
+                const T&                                                    \
+            >                                                               \
+        >::type                                                             \
+    > : Base                                                                \
     {                                                                       \
-        friend typename derived<Base>::type&                                \
-        operator op(typename derived<Base>::type& lhs,                      \
+        friend typename detail::non_const_this_param<Base>::type&           \
+        operator op(typename detail::non_const_this_param<Base>::type& lhs, \
                     typename as_param<Base, const U&>::type rhs)            \
         {                                                                   \
             ::boost::type_erasure::call(name<T, U>(),lhs, rhs);             \
@@ -392,7 +426,11 @@
 /// \cond show_operators
 
 template<class R, class T, class N, class Base>
-struct concept_interface<subscriptable<R, T, N>, Base, T> : Base
+struct concept_interface<subscriptable<R, T, N>, Base, typename ::boost::remove_const<T>::type,
+    typename ::boost::enable_if<
+        ::boost::type_erasure::detail::should_be_non_const<T, Base>
+    >::type
+> : Base
 {
     typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
         typename ::boost::type_erasure::as_param<Base, const N&>::type index)
@@ -402,7 +440,11 @@
 };
 
 template<class R, class T, class N, class Base>
-struct concept_interface<subscriptable<R, const T, N>, Base, T> : Base
+struct concept_interface<subscriptable<R, T, N>, Base, typename ::boost::remove_const<T>::type,
+    typename ::boost::enable_if<
+        ::boost::type_erasure::detail::should_be_const<T, Base>
+    >::type
+> : Base
 {
     typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
         typename ::boost::type_erasure::as_param<Base, const N&>::type index) const
@@ -428,8 +470,8 @@
 template<class Base, class Os, class T>
 struct concept_interface<ostreamable<Os, T>, Base, Os> : Base
 {
-    friend typename ::boost::type_erasure::derived<Base>::type&
-    operator<<(typename ::boost::type_erasure::derived<Base>::type& lhs,
+    friend typename detail::non_const_this_param<Base>::type&
+    operator<<(typename detail::non_const_this_param<Base>::type& lhs,
                typename ::boost::type_erasure::as_param<Base, const T&>::type rhs)
     {
         ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
@@ -472,8 +514,8 @@
 template<class Base, class Is, class T>
 struct concept_interface<istreamable<Is, T>, Base, Is> : Base
 {
-    friend typename ::boost::type_erasure::derived<Base>::type&
-    operator>>(typename ::boost::type_erasure::derived<Base>::type& lhs,
+    friend typename detail::non_const_this_param<Base>::type&
+    operator>>(typename detail::non_const_this_param<Base>::type& lhs,
                typename ::boost::type_erasure::as_param<Base, T&>::type rhs)
     {
         ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
Modified: sandbox/type_erasure/libs/type_erasure/example/references.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/references.cpp	(original)
+++ sandbox/type_erasure/libs/type_erasure/example/references.cpp	2012-10-08 19:37:00 EDT (Mon, 08 Oct 2012)
@@ -126,25 +126,6 @@
 
             any<incrementable<>, _self&> z(y); // error
             ++y; // error
-
-        There is one subtlety about this. The proxy reference
-        can have its own const qualifiers.  In most cases,
-        the effect is cumulative.
-     */
-    const any<incrementable<>, _self&> z(x);
-    /*`
-        `z` is treated as a reference to const even though we
-        used `_self&` instead of `const _self&`.
-
-            ++z; // error
-
-        The one exception to this is the constructor.  The
-        following is well-formed, even though `z` is const.
-     */
-    any<incrementable<>, _self&> w(z);
-    /*`
-        This behavior is not ideal, but anything else
-        is much too difficult to implement.
      */
     //]
 }