// Copyright (c) 2001-2010 Hartmut Kaiser // // 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) #if !defined(BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM) #define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// // This file contains attribute extraction utilities. The utilities // provided also accept spirit's unused_type; all no-ops. Compiler // optimization will easily strip these away. /////////////////////////////////////////////////////////////////////////// namespace detail { /////////////////////////////////////////////////////////////////////// // extract first and second element of a fusion sequence template struct add_const_ref : add_reference::type> {}; template struct value_at_c : add_const_ref::type> {}; } // This is the default case: the plain attribute values template struct extract_from_attribute { typedef typename traits::one_element_sequence::type is_one_element_sequence; typedef typename mpl::eval_if< is_one_element_sequence , detail::value_at_c , mpl::identity >::type type; template static type call(Attribute const& attr, Context&, mpl::false_) { return attr; } // This handles the case where the attribute is a single element fusion // sequence. We silently extract the only element and treat it as the // attribute to generate output from. template static type call(Attribute const& attr, Context& ctx, mpl::true_) { return extract_from(fusion::at_c<0>(attr), ctx); } template static type call(Attribute const& attr, Context& ctx) { return call(attr, ctx, is_one_element_sequence()); } }; // This handles optional attributes. template struct extract_from_attribute, Exposed> { typedef Attribute const& type; template static type call(optional const& attr, Context& ctx) { return extract_from(boost::get(attr), ctx); } }; template struct extract_from_attribute, Exposed> { typedef Attribute const& type; template static type call(optional const& attr, Context& ctx) { return extract_from(boost::get(attr), ctx); } }; // This handles attributes wrapped inside a boost::ref(). template struct extract_from_attribute, Exposed> { typedef Attribute const& type; template static type call(reference_wrapper const& attr, Context& ctx) { return extract_from(attr.get(), ctx); } }; /////////////////////////////////////////////////////////////////////////// template typename spirit::result_of::extract_from::type extract_from(Attribute const& attr, Context& ctx #if (defined(__GNUC__) && (__GNUC__ < 4)) || \ (defined(__APPLE__) && defined(__INTEL_COMPILER)) , typename enable_if >::type* #endif ) { return extract_from_attribute::call(attr, ctx); } template unused_type extract_from(unused_type, Context&) { return unused; } }}} /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace result_of { template struct extract_from : traits::extract_from_attribute {}; template struct extract_from { typedef unused_type type; }; template struct extract_from { typedef unused_type type; }; }}} #endif