// Copyright (c) 2001-2011 Hartmut Kaiser // Copyright (c) 2001-2011 Joel de Guzman // // 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(SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM) #define SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace qi { template struct default_transform_attribute { typedef Transformed type; static Transformed pre(Exposed&) { return Transformed(); } static void post(Exposed& val, Transformed const& attr) { traits::assign_to(attr, val); } // fail() will be called by Qi rule's if the rhs failed parsing static void fail(Exposed&) {} }; // handle case where no transformation is required as the types are the same template struct default_transform_attribute { typedef Attribute& type; static Attribute& pre(Attribute& val) { return val; } static void post(Attribute&, Attribute const&) {} static void fail(Attribute&) {} }; template struct proxy_transform_attribute { typedef Transformed type; static Transformed pre(Exposed& val) { return Transformed(val); } static void post(Exposed&, Transformed const&) { /* no-op */ } // fail() will be called by Qi rule's if the rhs failed parsing static void fail(Exposed&) {} }; // handle case where no transformation is required as the types are the same template struct proxy_transform_attribute { typedef Attribute& type; static Attribute& pre(Attribute& val) { return val; } static void post(Attribute&, Attribute const&) {} static void fail(Attribute&) {} }; // main specialization for Qi template struct transform_attribute : mpl::if_< mpl::and_< mpl::not_ > , mpl::not_ > , traits::is_proxy > , proxy_transform_attribute , default_transform_attribute >::type {}; template struct transform_attribute, Transformed , typename disable_if, Transformed> >::type> { typedef Transformed& type; static Transformed& pre(boost::optional& val) { if (!val) val = Transformed(); return boost::get(val); } static void post(boost::optional&, Transformed const&) {} static void fail(boost::optional& val) { val = none_t(); // leave optional uninitialized if rhs failed } }; // reference types need special handling template struct transform_attribute { typedef Attribute& type; static Attribute& pre(Attribute& val) { return val; } static void post(Attribute&, Attribute const&) {} static void fail(Attribute&) {} }; // unused_type needs some special handling as well template <> struct transform_attribute { typedef unused_type type; static unused_type pre(unused_type) { return unused; } static void post(unused_type, unused_type) {} static void fail(unused_type) {} }; template <> struct transform_attribute : transform_attribute {}; template struct transform_attribute : transform_attribute {}; template struct transform_attribute : transform_attribute {}; template struct transform_attribute : transform_attribute {}; template struct transform_attribute : transform_attribute {}; }}} /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace traits { template struct transform_attribute : qi::transform_attribute {}; template struct transform_attribute : transform_attribute {}; template struct transform_attribute : qi::transform_attribute {}; /////////////////////////////////////////////////////////////////////////// template void post_transform(Exposed& dest, Transformed const& attr) { return transform_attribute::post(dest, attr); } /////////////////////////////////////////////////////////////////////////// template void fail_transform(Exposed& dest, Transformed const&) { return transform_attribute::fail(dest); } }}} #endif