Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: http://spirit.sourceforge.net/ Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: #ifndef BOOST_SPIRIT_MODIFY_OCTOBER_25_2008_0142PM Chris@16: #define BOOST_SPIRIT_MODIFY_OCTOBER_25_2008_0142PM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include // needs to be included before proto Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: template Chris@16: struct is_modifier_directive; Chris@16: Chris@16: // Testing if a modifier set includes a modifier T involves Chris@16: // checking for inheritance (i.e. Modifiers is derived from T) Chris@16: template Chris@16: struct has_modifier Chris@16: : is_base_of {}; Chris@16: Chris@16: // Adding modifiers is done using multi-inheritance Chris@16: template Chris@16: struct compound_modifier : Current, New Chris@16: { Chris@16: compound_modifier() Chris@16: : Current(), New() {} Chris@16: Chris@16: compound_modifier(Current const& current, New const& new_) Chris@16: : Current(current), New(new_) {} Chris@16: }; Chris@16: Chris@16: // Don't add if New is already in Current Chris@16: template Chris@16: struct compound_modifier< Chris@16: Current, New, typename enable_if >::type> Chris@16: : Current Chris@16: { Chris@16: compound_modifier() Chris@16: : Current() {} Chris@16: Chris@16: compound_modifier(Current const& current, New const&) Chris@16: : Current(current) {} Chris@16: }; Chris@16: Chris@16: // Special case if Current is unused_type Chris@16: template Chris@16: struct compound_modifier : New Chris@16: { Chris@16: compound_modifier() Chris@16: : New() {} Chris@16: Chris@16: compound_modifier(unused_type, New const& new_) Chris@16: : New(new_) {} Chris@16: }; Chris@16: Chris@16: // Domains may specialize this modify metafunction to allow Chris@16: // directives to add information to the Modifier template Chris@16: // parameter that is passed to the make_component metafunction. Chris@16: // By default, we return the modifiers untouched Chris@16: template Chris@16: struct modify Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_const< Chris@16: typename remove_reference::type>::type Chris@16: tag_type; Chris@16: typedef typename remove_const< Chris@16: typename remove_reference::type>::type Chris@16: modifiers_type; Chris@16: Chris@16: typedef typename mpl::if_< Chris@16: is_modifier_directive Chris@16: , compound_modifier Chris@16: , Modifiers>::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: operator()(Tag tag, Modifiers modifiers) const Chris@16: { Chris@16: return op(tag, modifiers, is_modifier_directive()); Chris@16: } Chris@16: Chris@16: template Chris@16: Modifiers Chris@16: op(Tag /*tag*/, Modifiers modifiers, mpl::false_) const Chris@16: { Chris@16: return modifiers; Chris@16: } Chris@16: Chris@16: template Chris@16: compound_modifier Chris@16: op(Tag tag, Modifiers modifiers, mpl::true_) const Chris@16: { Chris@16: return compound_modifier(modifiers, tag); Chris@16: } Chris@16: }; Chris@16: }} Chris@16: Chris@16: namespace boost { namespace proto Chris@16: { Chris@16: template Chris@16: struct is_callable > Chris@16: : mpl::true_ {}; Chris@16: }} Chris@16: Chris@16: #endif