/*============================================================================= Copyright (c) 2001-2010 Joel de Guzman Copyright (c) 2001-2010 Hartmut Kaiser http://spirit.sourceforge.net/ 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_ASSIGN_TO_APR_16_2006_0812PM) #define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// // This file contains assignment utilities. The utilities provided also // accept spirit's unused_type; all no-ops. Compiler optimization will // easily strip these away. /////////////////////////////////////////////////////////////////////////// template struct assign_to_attribute_from_iterators { static void call(Iterator const& first, Iterator const& last, Attribute& attr) { if (traits::is_empty(attr)) attr = Attribute(first, last); else { for (Iterator i = first; i != last; ++i) push_back(attr, *i); } } }; template struct assign_to_attribute_from_iterators< reference_wrapper, Iterator> { static void call(Iterator const& first, Iterator const& last , reference_wrapper attr) { if (traits::is_empty(attr)) attr = Attribute(first, last); else { for (Iterator i = first; i != last; ++i) push_back(attr, *i); } } }; template struct assign_to_attribute_from_iterators< iterator_range, Iterator> { static void call(Iterator const& first, Iterator const& last , iterator_range& attr) { attr = iterator_range(first, last); } }; template inline void assign_to(Iterator const& first, Iterator const& last, Attribute& attr) { assign_to_attribute_from_iterators:: call(first, last, attr); } template inline void assign_to(Iterator const&, Iterator const&, unused_type) { } /////////////////////////////////////////////////////////////////////////// template void assign_to(T const& val, Attribute& attr); template struct assign_to_attribute_from_value { typedef typename traits::one_element_sequence::type is_one_element_sequence; typedef typename mpl::eval_if< is_one_element_sequence , fusion::result_of::at_c , mpl::identity >::type type; template static void call(T_ const& val, Attribute& attr, mpl::false_) { attr = static_cast(val); } // This handles the case where the attribute is a single element fusion // sequence. We silently assign to the only element and treat it as the // attribute to parse the results into. template static void call(T_ const& val, Attribute& attr, mpl::true_) { typedef typename fusion::result_of::value_at_c::type element_type; fusion::at_c<0>(attr) = static_cast(val); } static void call(T const& val, Attribute& attr) { call(val, attr, is_one_element_sequence()); } }; template struct assign_to_attribute_from_value { static void call(Attribute const& val, Attribute& attr) { attr = val; } }; template struct assign_to_attribute_from_value, T> { static void call(T const& val, reference_wrapper attr) { assign_to(val.get(), attr); } }; template struct assign_to_attribute_from_value, unused_type> { static void call(unused_type, optional const&) { } }; /////////////////////////////////////////////////////////////////////////// template inline void assign_to(T const& val, Attribute& attr) { assign_to_attribute_from_value::call(val, attr); } template inline void assign_to(T const&, unused_type) { } }}} #endif