$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78443 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-05-12 20:17:09
Author: steven_watanabe
Date: 2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
New Revision: 78443
URL: http://svn.boost.org/trac/boost/changeset/78443
Log:
Initial implementation of same_type.  Start rewriting iterators to use deduced.
Added:
   sandbox/type_erasure/boost/type_erasure/detail/normalize_deduced.hpp   (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/same_type.hpp   (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_same_type.cpp   (contents, props changed)
Text files modified: 
   sandbox/type_erasure/boost/type_erasure/any.hpp                        |    12 ++                                      
   sandbox/type_erasure/boost/type_erasure/binding.hpp                    |    13 ++                                      
   sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp           |   212 ++++++++++++++++++++++++++++++++++++++- 
   sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp |    31 ++++                                    
   sandbox/type_erasure/boost/type_erasure/iterator.hpp                   |    53 ++++++++-                               
   sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam                |     1                                         
   sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp  |    40 ++++++                                  
   7 files changed, 337 insertions(+), 25 deletions(-)
Modified: sandbox/type_erasure/boost/type_erasure/any.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/any.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/any.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -1034,6 +1034,18 @@
       : data(::boost::type_erasure::detail::access::data(other)),
         table(binding_arg)
     {}
+
+    any& operator=(const any& other)
+    {
+        ::boost::type_erasure::call(assignable<T, T>(), *this, other);
+        return *this;
+    }
+    template<class U>
+    any& operator=(const any<Concept, U>& other)
+    {
+        ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+        return *this;
+    }
 private:
     friend struct ::boost::type_erasure::detail::access;
     ::boost::type_erasure::detail::storage data;
Modified: sandbox/type_erasure/boost/type_erasure/binding.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/binding.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/binding.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -38,6 +38,9 @@
     >::type actual_concept;
     typedef typename ::boost::type_erasure::detail::make_vtable<
         actual_concept>::type table_type;
+    typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
+        Concept
+    >::type placeholder_subs;
 public:
     
     /**
@@ -149,9 +152,15 @@
     void set()
     {
         table = &::boost::type_erasure::detail::make_vtable_init<
-            typename ::boost::mpl::transform<actual_concept,
+            typename ::boost::mpl::transform<
+                actual_concept,
                 ::boost::type_erasure::detail::rebind_placeholders<
-                    ::boost::mpl::_1, Bindings>
+                    ::boost::mpl::_1,
+                    typename ::boost::type_erasure::detail::add_deductions<
+                        Bindings,
+                        placeholder_subs
+                    >::type
+                >
             >::type,
             table_type
         >::type::value;
Modified: sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -12,27 +12,183 @@
 #define BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_HPP_INCLUDED
 
 #include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/fold.hpp>
+#include <boost/mpl/identity.hpp>
 #include <boost/mpl/is_sequence.hpp>
 #include <boost/mpl/set.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/mpl/has_key.hpp>
 #include <boost/mpl/insert.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/inserter.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/transform.hpp>
 #include <boost/mpl/copy.hpp>
 #include <boost/type_erasure/detail/get_placeholders.hpp>
+#include <boost/type_erasure/detail/rebind_placeholders.hpp>
+#include <boost/type_erasure/detail/normalize_deduced.hpp>
 #include <boost/type_erasure/relaxed_match.hpp>
 #include <boost/type_erasure/builtin.hpp>
 
 namespace boost {
 namespace type_erasure {
+
+template<class F>
+struct deduced;
+
+template<class T, class U>
+struct same_type;
+
 namespace detail {
 
-template<class Concept, class Out = ::boost::mpl::set0<> >
+template<class Out, class T>
+struct insert_concept
+{
+    typedef ::boost::mpl::pair<
+        typename ::boost::mpl::insert<typename Out::first, T>::type,
+        typename Out::second
+    > type;
+};
+
+template<class M, class T>
+struct resolve_same_type
+{
+    typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
+        ::boost::type_erasure::detail::resolve_same_type<
+            M,
+            typename ::boost::mpl::at<M, T>::type
+        >,
+        ::boost::mpl::identity<T>
+    >::type type;
+};
+
+template<class T, class U>
+struct select_pair
+{
+    // error: cannot resolve conflict
+};
+
+template<class T, class U>
+struct select_pair<T, ::boost::type_erasure::deduced<U> >
+{
+    typedef ::boost::mpl::pair<T, ::boost::type_erasure::deduced<U> > type;
+};
+
+template<class T, class U>
+struct select_pair< ::boost::type_erasure::deduced<T>, U>
+{
+    typedef ::boost::mpl::pair< ::boost::type_erasure::deduced<T>, U> type;
+};
+
+template<class T, class U>
+struct select_pair<
+    ::boost::type_erasure::deduced<T>,
+    ::boost::type_erasure::deduced<U>
+>
+{
+    typedef ::boost::mpl::pair<
+        ::boost::type_erasure::deduced<T>,
+        ::boost::type_erasure::deduced<U>
+    > type;
+};
+
+template<class M, class T>
+struct normalize_placeholder
+{
+    typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
+        ::boost::type_erasure::detail::normalize_placeholder<
+            M,
+            typename ::boost::mpl::at<M, T>::type
+        >,
+        ::boost::mpl::identity<T>
+    >::type type;
+};
+
+template<class M, class T>
+struct normalize_placeholder<M, ::boost::type_erasure::deduced<T> >
+{
+    typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
+        ::boost::type_erasure::detail::normalize_placeholder<
+            M,
+            typename ::boost::mpl::at<M, T>::type
+        >,
+        ::boost::type_erasure::detail::normalize_deduced<
+            M,
+            T
+        >
+    >::type type;
+};
+
+template<class M>
+struct create_placeholder_map
+{
+    typedef typename ::boost::mpl::fold<
+        M,
+        ::boost::mpl::map0<>,
+        ::boost::mpl::insert<
+            ::boost::mpl::_1,
+            ::boost::mpl::pair<
+                ::boost::mpl::first< ::boost::mpl::_2>,
+                ::boost::type_erasure::detail::normalize_placeholder<M, ::boost::mpl::second< ::boost::mpl::_2> >
+            >
+        >
+    >::type type;
+};
+
+template<class Bindings, class P, class Out>
+struct add_deduced
+{
+    typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
+        typename P::first,
+        Bindings
+    >::type result;
+    typedef typename ::boost::mpl::eval_if<
+        ::boost::mpl::has_key<Out, typename P::second>,
+        ::boost::mpl::identity<Out>,
+        ::boost::mpl::insert<Out, ::boost::mpl::pair<typename P::second, result> >
+    >::type type;
+    BOOST_MPL_ASSERT((boost::is_same<typename ::boost::mpl::at<type, typename P::second>::type, result>));
+};
+
+template<class Bindings, class M>
+struct add_deductions
+{
+    typedef typename ::boost::mpl::fold<
+        M,
+        Bindings,
+        ::boost::type_erasure::detail::add_deduced<
+            Bindings, ::boost::mpl::_2, ::boost::mpl::_1
+        >
+    >::type type;
+};
+
+template<class Out, class T, class U>
+struct insert_concept<Out, ::boost::type_erasure::same_type<T, U> >
+{
+    typedef ::boost::mpl::pair<
+        typename Out::first,
+        typename ::boost::mpl::insert<
+            typename Out::second,
+            typename ::boost::type_erasure::detail::select_pair<
+                typename ::boost::type_erasure::detail::resolve_same_type<
+                    typename Out::second,
+                    T
+                >::type,
+                typename ::boost::type_erasure::detail::resolve_same_type<
+                    typename Out::second,
+                    U
+                >::type
+            >::type
+        >::type
+    > type;
+};
+
+template<class Concept, class Out = ::boost::mpl::pair< ::boost::mpl::set0<>, ::boost::mpl::map0<> > >
 struct normalize_concept_impl
 {
     typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
         ::boost::mpl::fold<Concept, Out, normalize_concept_impl< ::boost::mpl::_2, ::boost::mpl::_1> >,
-        ::boost::mpl::insert<Out, Concept>
+        ::boost::type_erasure::detail::insert_concept<Out, Concept>
     >::type type;
 };
 
@@ -67,9 +223,31 @@
 };
 
 template<class Concept>
+struct get_placeholder_normalization_map
+{
+    typedef typename ::boost::type_erasure::detail::create_placeholder_map<
+        typename normalize_concept_impl<Concept>::type::second
+    >::type type;
+};
+
+template<class Concept>
 struct normalize_concept
 {
-    typedef typename normalize_concept_impl<Concept>::type basic;
+    typedef typename normalize_concept_impl<Concept>::type impl;
+    typedef typename ::boost::type_erasure::detail::create_placeholder_map<
+        typename impl::second
+    >::type substitutions;
+    typedef typename ::boost::mpl::fold<
+        typename impl::first,
+        ::boost::mpl::set0<>,
+        ::boost::mpl::insert<
+            ::boost::mpl::_1,
+            ::boost::type_erasure::detail::rebind_placeholders<
+                ::boost::mpl::_2,
+                substitutions
+            >
+        >
+    >::type basic;
     typedef typename ::boost::mpl::copy<
         typename ::boost::mpl::eval_if<
             ::boost::type_erasure::is_relaxed<Concept>,
@@ -80,15 +258,31 @@
     >::type type;
 };
 
-template<class Concept, class Out = ::boost::mpl::set0<> >
+template<
+    class Concept,
+    class Map = typename ::boost::type_erasure::detail::create_placeholder_map<
+            typename ::boost::type_erasure::detail::normalize_concept_impl<
+                Concept
+            >::type::second
+        >::type,
+    class Out = ::boost::mpl::set0<>
+>
 struct collect_concepts
 {
-    typedef typename ::boost::mpl::insert<
-        Out,
-        Concept
+    typedef typename ::boost::type_erasure::detail::rebind_placeholders<
+        Concept,
+        Map
+    >::type transformed;
+    typedef typename ::boost::mpl::eval_if<
+        ::boost::is_same<transformed, void>,
+        ::boost::mpl::identity<Out>,
+        ::boost::mpl::insert<
+            Out,
+            transformed
+        >
     >::type type1;
     typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
-        ::boost::mpl::fold<Concept, type1, collect_concepts< ::boost::mpl::_2, ::boost::mpl::_1> >,
+        ::boost::mpl::fold<Concept, type1, collect_concepts< ::boost::mpl::_2, Map, ::boost::mpl::_1> >,
         ::boost::mpl::identity<type1>
     >::type type;
 };
Added: sandbox/type_erasure/boost/type_erasure/detail/normalize_deduced.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/normalize_deduced.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -0,0 +1,61 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 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$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_DEDUCED_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_DEDUCED_HPP_INCLUDED
+
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class M, class T>
+struct normalize_deduced;
+template<class M, class T>
+struct normalize_placeholder;
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/normalize_deduced.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_NORMALIZE_PLACEHOLDER(z, n, data)        \
+    typename ::boost::type_erasure::detail::normalize_placeholder<  \
+        M,                                                          \
+        BOOST_PP_CAT(U, n)                                          \
+    >::type
+
+template<class M, template<BOOST_PP_ENUM_PARAMS(N, class T)> class T, BOOST_PP_ENUM_PARAMS(N, class U)>
+struct normalize_deduced<M, T<BOOST_PP_ENUM_PARAMS(N, U)> >
+{
+    typedef typename ::boost::type_erasure::deduced<
+        T<BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_NORMALIZE_PLACEHOLDER, ~)>
+    >::type type;
+};
+
+#undef BOOST_TYPE_ERASURE_NORMALIZE_PLACEHOLDER
+
+#undef N
+
+#endif
Modified: sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -16,6 +16,7 @@
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/mpl/at.hpp>
+#include <boost/mpl/has_key.hpp>
 #include <boost/type_traits/is_base_and_derived.hpp>
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/iteration/iterate.hpp>
@@ -23,7 +24,6 @@
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
 #include <boost/type_erasure/config.hpp>
-#include <boost/type_erasure/is_placeholder.hpp>
 
 namespace boost {
 namespace type_erasure {
@@ -34,12 +34,16 @@
 namespace detail {
 
 template<class T, class Bindings>
-struct rebind_placeholders;
+struct rebind_placeholders
+{
+    typedef void type;
+};
 
 template<class T, class Bindings>
 struct rebind_placeholders_in_argument
 {
-    typedef typename ::boost::mpl::eval_if<is_placeholder<T>,
+    typedef typename ::boost::mpl::eval_if<
+        ::boost::mpl::has_key<Bindings, T>,
         ::boost::mpl::at<Bindings, T>,
         ::boost::mpl::identity<T>
     >::type type;
@@ -64,11 +68,28 @@
 };
 
 template<class F, class Bindings>
+struct rebind_placeholders_in_deduced
+{
+    typedef typename ::boost::type_erasure::deduced<
+        typename ::boost::type_erasure::detail::rebind_placeholders<F, Bindings>::type
+    >::type type;
+};
+
+template<class F, class Bindings>
 struct rebind_placeholders_in_argument<
     ::boost::type_erasure::deduced<F>,
     Bindings
-> : ::boost::type_erasure::detail::rebind_placeholders<F, Bindings>::type
-{};
+> 
+{
+    typedef typename ::boost::mpl::eval_if<
+        ::boost::mpl::has_key<Bindings, ::boost::type_erasure::deduced<F> >,
+        ::boost::mpl::at<Bindings, ::boost::type_erasure::deduced<F> >,
+        ::boost::type_erasure::detail::rebind_placeholders_in_deduced<
+            F,
+            Bindings
+        >
+    >::type type;
+};
 
 #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
 
Modified: sandbox/type_erasure/boost/type_erasure/iterator.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/iterator.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/iterator.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -13,13 +13,43 @@
 
 #include <iterator>
 #include <boost/mpl/vector.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 #include <boost/type_erasure/operators.hpp>
 #include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/deduced.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
 
 namespace boost {
 namespace type_erasure {
 
-template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Pointer = ValueType*, class Reference = ValueType&>
+namespace detail {
+
+template<class T>
+struct iterator_value_type_impl
+{
+    typedef typename ::std::iterator_traits<T>::value_type type;
+};
+
+}
+
+template<class T>
+struct iterator_value_type
+{
+    typedef typename ::boost::mpl::eval_if<
+        ::boost::type_erasure::is_placeholder<T>,
+        ::boost::mpl::identity<void>,
+        ::boost::type_erasure::detail::iterator_value_type_impl<T>
+    >::type type;
+};
+
+template<
+    class T = _self,
+    class ValueType = typename ::boost::type_erasure::deduced<iterator_value_type<T> >::type,
+    class DifferenceType = ::std::ptrdiff_t,
+    class Reference = ValueType&
+>
 struct forward_iterator :
     boost::mpl::vector<
         copy_constructible<T>,
@@ -29,24 +59,33 @@
         incrementable<T>,
         assignable<T>
     >
-{};
+{
+    typedef typename ::boost::remove_const<ValueType>::type value_type;
+    typedef DifferenceType difference_type;
+    typedef Reference reference;
+};
 
 /// \cond show_operators
 
-template<class T, class ValueType, class DifferenceType, class Pointer, class Reference, class Base>
-struct concept_interface<forward_iterator<T, ValueType, DifferenceType, Pointer, Reference>, Base, T>
+template<class T, class ValueType, class DifferenceType, class Reference, class Base>
+struct concept_interface<forward_iterator<T, ValueType, DifferenceType, Reference>, Base, T>
     : Base
 {
     typedef typename rebind_any<Base, ValueType>::type value_type;
     typedef typename rebind_any<Base, Reference>::type reference;
     typedef DifferenceType difference_type;
-    typedef Pointer pointer;
+    typedef typename ::boost::mpl::if_< ::boost::is_reference<reference>,
+        typename ::boost::remove_reference<reference>::type*,
+        value_type*
+    >::type pointer;
     typedef std::forward_iterator_tag iterator_category;
 };
 
 /// \endcond
 
-template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Pointer = ValueType*, class Reference = ValueType&>
+#if 0
+
+template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Reference = ValueType&>
 struct bidirectional_iterator :
     boost::mpl::vector<
         forward_iterator<T, ValueType, DifferenceType, Pointer, Reference>,
@@ -88,6 +127,8 @@
 
 /// \endcond
 
+#endif
+
 }
 }
 
Added: sandbox/type_erasure/boost/type_erasure/same_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/same_type.hpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -0,0 +1,28 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 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_SAME_TYPE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_SAME_TYPE_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * A built in concept that indicates that two
+ * types are the same.  Either T or U or both
+ * can be placeholders.
+ */
+template<class T, class U>
+struct same_type {};
+
+}
+}
+
+#endif
Modified: sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam	(original)
+++ sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -31,6 +31,7 @@
 run test_tuple.cpp /boost//unit_test_framework ;
 run test_stream.cpp /boost//unit_test_framework ;
 run test_deduced.cpp /boost//unit_test_framework ;
+run test_same_type.cpp /boost//unit_test_framework ;
 
 compile-fail fail_increment_discard_const.cpp ;
 
Modified: sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp	(original)
+++ sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -13,7 +13,8 @@
 #include <boost/type_erasure/operators.hpp>
 #include <boost/type_erasure/any_cast.hpp>
 #include <boost/type_erasure/iterator.hpp>
-#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/same_type.hpp>
+#include <boost/type_erasure/binding_of.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/concept_check.hpp>
 
@@ -24,7 +25,10 @@
 
 BOOST_AUTO_TEST_CASE(test_basic)
 {
-    typedef boost::mpl::vector<forward_iterator<_self, int> > test_concept;
+    typedef boost::mpl::vector<
+        forward_iterator<>,
+        same_type<forward_iterator<>::value_type, int>
+    > test_concept;
     std::vector<int> vec(10);
     any<test_concept> x(vec.begin());
     any<test_concept> y(vec.end());
@@ -42,9 +46,39 @@
     BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::iterator_category, std::forward_iterator_tag>));
 }
 
+BOOST_AUTO_TEST_CASE(test_any_value_type)
+{
+    typedef boost::mpl::vector<
+        forward_iterator<>,
+        same_type<forward_iterator<>::value_type, _a>,
+        copy_constructible<_a>,
+        assignable<_a>,
+        incrementable<_a>
+    > test_concept;
+    std::vector<int> vec(10);
+    any<test_concept> x(vec.begin());
+    any<test_concept> y(vec.end());
+
+    for(any<test_concept, _a> i = *x; x != y; ++x, ++i) {
+        *x = i;
+    }
+    int expected[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    BOOST_CHECK_EQUAL_COLLECTIONS(vec.begin(), vec.end(), &expected[0], &expected[0] + 10);
+
+    BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::value_type, any<test_concept, _a> >));
+    BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::reference, any<test_concept, _a&> >));
+    BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::pointer, any<test_concept, _a>*>));
+    BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::difference_type, std::ptrdiff_t>));
+    BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::iterator_category, std::forward_iterator_tag>));
+}
+
 BOOST_AUTO_TEST_CASE(test_relaxed)
 {
-    typedef boost::mpl::vector<forward_iterator<_self, int>, relaxed_match> test_concept;
+    typedef boost::mpl::vector<
+        forward_iterator<>,
+        same_type<forward_iterator<>::value_type, int>,
+        relaxed_match
+    > test_concept;
     std::vector<int> vec(10);
     any<test_concept> x(vec.begin());
     any<test_concept> y(vec.end());
Added: sandbox/type_erasure/libs/type_erasure/test/test_same_type.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_same_type.cpp	2012-05-12 20:17:07 EDT (Sat, 12 May 2012)
@@ -0,0 +1,48 @@
+// 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$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/deduced.hpp>
+#include <boost/type_erasure/same_type.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+BOOST_AUTO_TEST_CASE(test_deduce_dereference)
+{
+    typedef ::boost::mpl::vector<
+        copy_constructible<>,
+        typeid_<_a>,
+        dereferenceable<deduced<boost::remove_pointer<_self> >&>,
+        same_type<deduced<boost::remove_pointer<_self> >, _a>
+    > test_concept;
+    int i;
+
+    any<test_concept> x(&i);
+    any<test_concept, _a&> y(*x);
+    BOOST_CHECK_EQUAL(&any_cast<int&>(y), &i);
+}
+
+BOOST_MPL_ASSERT((
+    boost::is_same<
+        deduced<boost::remove_pointer<_self> >::type,
+        deduced<boost::remove_pointer<_self> > >));
+
+BOOST_MPL_ASSERT((
+    boost::is_same<deduced<boost::remove_pointer<int*> >::type, int >));