PageRenderTime 34ms CodeModel.GetById 23ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/karma/directive/as.hpp

http://hadesmem.googlecode.com/
C++ Header | 165 lines | 124 code | 21 blank | 20 comment | 1 complexity | 50e37559a8faa6f9bfebad009399c3cb MD5 | raw file
  1//  Copyright (c) 2001-2011 Hartmut Kaiser
  2//  Copyright (c)      2010 Bryce Lelbach
  3//
  4//  Distributed under the Boost Software License, Version 1.0. (See accompanying
  5//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6
  7#if !defined(SPIRIT_KARMA_AS_DEC_18_0510PM)
  8#define SPIRIT_KARMA_AS_DEC_18_0510PM
  9
 10#if defined(_MSC_VER)
 11#pragma once
 12#endif
 13
 14#include <boost/spirit/home/karma/meta_compiler.hpp>
 15#include <boost/spirit/home/karma/generator.hpp>
 16#include <boost/spirit/home/karma/domain.hpp>
 17#include <boost/spirit/home/karma/detail/output_iterator.hpp>
 18#include <boost/spirit/home/karma/detail/as.hpp>
 19#include <boost/spirit/home/support/unused.hpp>
 20#include <boost/spirit/home/support/info.hpp>
 21#include <boost/spirit/home/support/common_terminals.hpp>
 22#include <boost/spirit/home/support/has_semantic_action.hpp>
 23#include <boost/spirit/home/support/handles_container.hpp>
 24#include <boost/spirit/home/support/assert_msg.hpp>
 25#include <boost/spirit/home/support/container.hpp>
 26#include <boost/spirit/home/karma/detail/attributes.hpp>
 27
 28namespace boost { namespace spirit { namespace karma
 29{
 30    template <typename T>
 31    struct as
 32      : stateful_tag_type<T, tag::as>
 33    {
 34        BOOST_SPIRIT_ASSERT_MSG(
 35            (traits::is_container<T>::type::value),
 36            error_type_must_be_a_container,
 37            (T));
 38    };
 39}}}
 40
 41namespace boost { namespace spirit
 42{
 43    ///////////////////////////////////////////////////////////////////////////
 44    // Enablers
 45    ///////////////////////////////////////////////////////////////////////////
 46    // enables as_string[...]
 47    template <>
 48    struct use_directive<karma::domain, tag::as_string> 
 49      : mpl::true_ {};
 50
 51    // enables as_wstring[...]
 52    template <>
 53    struct use_directive<karma::domain, tag::as_wstring> 
 54      : mpl::true_ {};
 55
 56    // enables as<T>[...]
 57    template <typename T>
 58    struct use_directive<karma::domain, tag::stateful_tag<T, tag::as> > 
 59      : mpl::true_ 
 60    {};
 61}}
 62
 63namespace boost { namespace spirit { namespace karma
 64{
 65#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
 66    using spirit::as_string;
 67    using spirit::as_wstring;
 68#endif
 69    using spirit::as_string_type;
 70    using spirit::as_wstring_type;
 71
 72    ///////////////////////////////////////////////////////////////////////////
 73    // as_directive allows to hook custom conversions to string into the
 74    // output generation process
 75    ///////////////////////////////////////////////////////////////////////////
 76    template <typename Subject, typename T>
 77    struct as_directive 
 78      : unary_generator<as_directive<Subject, T> >
 79    {
 80        typedef Subject subject_type;
 81        typedef typename subject_type::properties properties;
 82
 83        as_directive(Subject const& subject)
 84          : subject(subject) {}
 85
 86        template <typename Context, typename Iterator>
 87        struct attribute
 88        {
 89            typedef T type;
 90        };
 91
 92        template <typename OutputIterator, typename Context, typename Delimiter
 93          , typename Attribute>
 94        bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
 95          , Attribute const& attr) const
 96        {
 97            if (!traits::valid_as<T>(attr))
 98                return false;
 99
100            return subject.generate(sink, ctx, d, traits::as<T>(attr)) &&
101                    karma::delimit_out(sink, d); // always do post-delimiting
102        }
103
104        template <typename Context>
105        info what(Context& context) const
106        {
107            return info("as", subject.what(context));
108        }
109
110        Subject subject;
111    };
112
113    ///////////////////////////////////////////////////////////////////////////
114    // Generator generators: make_xxx function (objects)
115    ///////////////////////////////////////////////////////////////////////////
116    template <typename Subject, typename Modifiers>
117    struct make_directive<tag::as_string, Subject, Modifiers>
118    {
119        typedef as_directive<Subject, std::string> result_type;
120        result_type operator()(unused_type, Subject const& subject
121          , unused_type) const
122        {
123            return result_type(subject);
124        }
125    };
126
127    template <typename Subject, typename Modifiers>
128    struct make_directive<tag::as_wstring, Subject, Modifiers>
129    {
130        typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
131        result_type operator()(unused_type, Subject const& subject
132          , unused_type) const
133        {
134            return result_type(subject);
135        }
136    };
137    
138    template <typename T, typename Subject, typename Modifiers>
139    struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
140    {
141        typedef as_directive<Subject, T> result_type;
142        result_type operator()(unused_type, Subject const& subject
143          , unused_type) const
144        {
145            return result_type(subject);
146        }
147    };
148}}}
149
150namespace boost { namespace spirit { namespace traits
151{
152    ///////////////////////////////////////////////////////////////////////////
153    template <typename Subject, typename T>
154    struct has_semantic_action<karma::as_directive<Subject, T> >
155      : unary_has_semantic_action<Subject> {};
156
157    ///////////////////////////////////////////////////////////////////////////
158    template <typename Subject, typename T, typename Attribute
159      , typename Context, typename Iterator>
160    struct handles_container<karma::as_directive<Subject, T>, Attribute
161      , Context, Iterator>
162      : mpl::false_ {};   // always dereference attribute if used in sequences
163}}}
164
165#endif