// Copyright (c) 2008 Dean Michael Berris // 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) #ifndef BOOST_SELECT_20080417 #define BOOST_SELECT_20080417 #include #include #include #include #include #include namespace boost { template struct select; namespace detail { ////////////////////////////////////////////////////////////////// // This is the expression template implementation that composes // a selector and a function object wrapper together to form a // single function object that takes a pair, and returns the // data which the function object wrapper would return. // template struct expr { explicit expr(select const & s, boost::function< typename boost::function_types::function_type< typename boost::function_types::components< Signature >::types >::type > f) : _selector(s), _function(f) { }; template typename boost::function_types::result_type::type operator()(Sequence & s) const { return _function(_selector(s)); }; private: select const & _selector; mutable boost::function< typename boost::function_types::function_type< typename boost::function_types::components< Signature >::types >::type > _function; }; // ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // This implementation uses simple compile-time logic to determine // whether at the call point the parameter to the function // operator overload is actually a fusion sequence. In the case // that it is, the result type is computed using fusion::at_c, // otherwise it is turned into a fusion sequence and the correct // value is returned. // template struct select_impl_fusion { template struct result { typedef typename boost::fusion::result_of::at_c::type type; }; template typename result::type operator() (Sequence & s) const { return boost::fusion::at_c(s); }; }; // ////////////////////////////////////////////////////////////////// }; // namespace detail template struct select : detail::select_impl_fusion { }; // ////////////////////////////////////////////////////////////////// typedef select<0> first; // convenience selector typedef select<1> second; // convenience selector typedef select<2> third; // convenience selector ////////////////////////////////////////////////////////////////// // Implementation of the pipe operator overload, to allow chaining // of the selector function object instance and passing the // output of the selection to an actual function object. // template detail::expr operator| (select const & selector, Signature f) { return detail::expr(selector, f); }; // ////////////////////////////////////////////////////////////////// }; // namespace boost #endif