Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80883 - in sandbox/type_erasure/boost/type_erasure: . detail
From: steven_at_[hidden]
Date: 2012-10-05 21:28:13


Author: steven_watanabe
Date: 2012-10-05 21:28:13 EDT (Fri, 05 Oct 2012)
New Revision: 80883
URL: http://svn.boost.org/trac/boost/changeset/80883

Log:
Add early check for concept conversions.
Added:
   sandbox/type_erasure/boost/type_erasure/detail/check_map.hpp (contents, props changed)
Text files modified:
   sandbox/type_erasure/boost/type_erasure/binding.hpp | 25 +++++++++++++++++++++++--
   sandbox/type_erasure/boost/type_erasure/is_subconcept.hpp | 8 ++++++++
   2 files changed, 31 insertions(+), 2 deletions(-)

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-10-05 21:28:13 EDT (Fri, 05 Oct 2012)
@@ -14,6 +14,7 @@
 #include <boost/config.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/make_shared.hpp>
+#include <boost/utility/enable_if.hpp>
 #include <boost/mpl/transform.hpp>
 #include <boost/mpl/find_if.hpp>
 #include <boost/mpl/and.hpp>
@@ -23,12 +24,14 @@
 #include <boost/mpl/pair.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_erasure/static_binding.hpp>
+#include <boost/type_erasure/is_subconcept.hpp>
 #include <boost/type_erasure/detail/adapt_to_vtable.hpp>
 #include <boost/type_erasure/detail/null.hpp>
 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
 #include <boost/type_erasure/detail/vtable.hpp>
 #include <boost/type_erasure/detail/normalize.hpp>
 #include <boost/type_erasure/detail/instantiate.hpp>
+#include <boost/type_erasure/detail/check_map.hpp>
 
 namespace boost {
 namespace type_erasure {
@@ -119,7 +122,16 @@
      * \throws std::bad_alloc
      */
     template<class Concept2, class Map>
- binding(const binding<Concept2>& other, const Map&)
+ binding(const binding<Concept2>& other, const Map&
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::enable_if<
+ ::boost::mpl::and_<
+ ::boost::type_erasure::detail::check_map<Concept, Map>,
+ ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
+ >
+ >::type* = 0
+#endif
+ )
       : impl(
             other,
             static_binding<Map>(),
@@ -137,7 +149,16 @@
      * \throws std::bad_alloc
      */
     template<class Concept2, class Map>
- binding(const binding<Concept2>& other, const static_binding<Map>&)
+ binding(const binding<Concept2>& other, const static_binding<Map>&
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::enable_if<
+ ::boost::mpl::and_<
+ ::boost::type_erasure::detail::check_map<Concept, Map>,
+ ::boost::type_erasure::is_subconcept<Concept, Concept2, Map>
+ >
+ >::type* = 0
+#endif
+ )
       : impl(
             other,
             static_binding<Map>(),

Added: sandbox/type_erasure/boost/type_erasure/detail/check_map.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/check_map.hpp 2012-10-05 21:28:13 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,85 @@
+// 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_CHECK_MAP_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_CHECK_MAP_HPP_INCLUDED
+
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/set.hpp>
+#include <boost/mpl/has_key.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_erasure/detail/get_placeholders.hpp>
+#include <boost/type_erasure/deduced.hpp>
+#include <boost/type_erasure/static_binding.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class T>
+struct is_deduced : boost::mpl::false_ {};
+template<class T>
+struct is_deduced< ::boost::type_erasure::deduced<T> > : boost::mpl::true_ {};
+
+// returns true if Map has a key for every non-deduced placeholder in Concept
+template<class Concept, class Map>
+struct check_map {
+ typedef typename normalize_concept<Concept>::basic basic_components;
+
+ // Every non-deduced placeholder referenced in this
+ // map is indirectly deduced.
+ typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
+ Concept>::type placeholder_subs;
+ typedef typename ::boost::mpl::fold<
+ placeholder_subs,
+ ::boost::mpl::set0<>,
+ ::boost::mpl::insert<
+ ::boost::mpl::_1,
+ ::boost::mpl::second< ::boost::mpl::_2>
+ >
+ >::type indirect_deduced_placeholders;
+
+ typedef typename ::boost::mpl::fold<
+ basic_components,
+ ::boost::mpl::set0<>,
+ ::boost::type_erasure::detail::get_placeholders<
+ ::boost::mpl::_2,
+ ::boost::mpl::_1
+ >
+ >::type placeholders;
+ typedef typename ::boost::is_same<
+ typename ::boost::mpl::find_if<
+ placeholders,
+ ::boost::mpl::not_<
+ ::boost::mpl::or_<
+ ::boost::type_erasure::detail::is_deduced< ::boost::mpl::_1>,
+ ::boost::mpl::has_key<Map, ::boost::mpl::_1>,
+ ::boost::mpl::has_key<indirect_deduced_placeholders, ::boost::mpl::_1>
+ >
+ >
+ >::type,
+ typename ::boost::mpl::end<placeholders>::type
+ >::type type;
+};
+
+template<class Concept, class Map>
+struct check_map<Concept, ::boost::type_erasure::static_binding<Map> > :
+ check_map<Concept, Map>
+{};
+
+}
+}
+}
+
+#endif

Modified: sandbox/type_erasure/boost/type_erasure/is_subconcept.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/is_subconcept.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/is_subconcept.hpp 2012-10-05 21:28:13 EDT (Fri, 05 Oct 2012)
@@ -20,6 +20,7 @@
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_erasure/detail/normalize.hpp>
 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
+#include <boost/type_erasure/static_binding.hpp>
 
 namespace boost {
 namespace type_erasure {
@@ -94,6 +95,13 @@
 struct is_subconcept : ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>::type {
 };
 
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+template<class Sub, class Super, class PlaceholderMap>
+struct is_subconcept<Sub, Super, static_binding<PlaceholderMap> > :
+ ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>::type
+{};
+#endif
+
 }
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk