PageRenderTime 10ms CodeModel.GetById 1ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/support/modify.hpp

http://hadesmem.googlecode.com/
C++ Header | 124 lines | 90 code | 18 blank | 16 comment | 0 complexity | 733ebd4ea7d372d6744d22d3b9b73b86 MD5 | raw file
  1/*=============================================================================
  2  Copyright (c) 2001-2011 Joel de Guzman
  3  http://spirit.sourceforge.net/
  4
  5  Distributed under the Boost Software License, Version 1.0. (See accompanying
  6  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7=============================================================================*/
  8#ifndef BOOST_SPIRIT_MODIFY_OCTOBER_25_2008_0142PM
  9#define BOOST_SPIRIT_MODIFY_OCTOBER_25_2008_0142PM
 10
 11#if defined(_MSC_VER)
 12#pragma once
 13#endif
 14
 15#include <boost/spirit/include/phoenix_limits.hpp>      // needs to be included before proto
 16#include <boost/proto/proto.hpp>
 17#include <boost/mpl/if.hpp>
 18#include <boost/type_traits/is_base_of.hpp>
 19#include <boost/spirit/home/support/unused.hpp>
 20
 21namespace boost { namespace spirit
 22{
 23    template <typename Domain, typename T, typename Enable = void>
 24    struct is_modifier_directive;
 25
 26    // Testing if a modifier set includes a modifier T involves
 27    // checking for inheritance (i.e. Modifiers is derived from T)
 28    template <typename Modifiers, typename T>
 29    struct has_modifier
 30        : is_base_of<T, Modifiers> {};
 31
 32    // Adding modifiers is done using multi-inheritance
 33    template <typename Current, typename New, typename Enable = void>
 34    struct compound_modifier : Current, New
 35    {
 36        compound_modifier()
 37          : Current(), New() {}
 38
 39        compound_modifier(Current const& current, New const& new_)
 40          : Current(current), New(new_) {}
 41    };
 42
 43    // Don't add if New is already in Current
 44    template <typename Current, typename New>
 45    struct compound_modifier<
 46        Current, New, typename enable_if<has_modifier<Current, New> >::type>
 47      : Current
 48    {
 49        compound_modifier()
 50          : Current() {}
 51
 52        compound_modifier(Current const& current, New const&)
 53          : Current(current) {}
 54    };
 55
 56    // Special case if Current is unused_type
 57    template <typename New, typename Enable>
 58    struct compound_modifier<unused_type, New, Enable> : New
 59    {
 60        compound_modifier()
 61          : New() {}
 62
 63        compound_modifier(unused_type, New const& new_)
 64          : New(new_) {}
 65    };
 66
 67    // Domains may specialize this modify metafunction to allow
 68    // directives to add information to the Modifier template
 69    // parameter that is passed to the make_component metafunction.
 70    // By default, we return the modifiers untouched
 71    template <typename Domain, typename Enable = void>
 72    struct modify
 73    {
 74        template <typename Sig>
 75        struct result;
 76
 77        template <typename This, typename Tag, typename Modifiers>
 78        struct result<This(Tag, Modifiers)>
 79        {
 80            typedef typename remove_const<
 81                typename remove_reference<Tag>::type>::type
 82            tag_type;
 83            typedef typename remove_const<
 84                typename remove_reference<Modifiers>::type>::type
 85            modifiers_type;
 86
 87            typedef typename mpl::if_<
 88                is_modifier_directive<Domain, tag_type>
 89              , compound_modifier<modifiers_type, tag_type>
 90              , Modifiers>::type
 91            type;
 92        };
 93
 94        template <typename Tag, typename Modifiers>
 95        typename result<modify(Tag, Modifiers)>::type
 96        operator()(Tag tag, Modifiers modifiers) const
 97        {
 98            return op(tag, modifiers, is_modifier_directive<Domain, Tag>());
 99        }
100
101        template <typename Tag, typename Modifiers>
102        Modifiers
103        op(Tag /*tag*/, Modifiers modifiers, mpl::false_) const
104        {
105            return modifiers;
106        }
107
108        template <typename Tag, typename Modifiers>
109        compound_modifier<Modifiers, Tag>
110        op(Tag tag, Modifiers modifiers, mpl::true_) const
111        {
112            return compound_modifier<Modifiers, Tag>(modifiers, tag);
113        }
114    };
115}}
116
117namespace boost { namespace proto
118{
119    template <typename Domain, typename Enable>
120    struct is_callable<spirit::modify<Domain, Enable> >
121      : mpl::true_ {};
122}}
123
124#endif