codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <boost/proto/proto.hpp> //////////////////////////////////////////////////////////////////////////////// // Strip potential parens around macro parameters. // Details are in http://article.gmane.org/gmane.comp.lib.boost.user/61011 //////////////////////////////////////////////////////////////////////////////// #define NT2_PP_DETAILS_APPLY(macro, args) NT2_PP_DETAILS_APPLY_I(macro, args) #define NT2_PP_DETAILS_APPLY_I(macro, args) macro args #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1 #define NT2_PP_DETAILS_EVAL(test, x) NT2_PP_DETAILS_EVAL_I(test, x) #define NT2_PP_DETAILS_EVAL_I(test, x) NT2_PP_DETAILS_MAYBE_STRIP_PARENS(NT2_PP_DETAILS_TEST_ARITY test, x) #define NT2_PP_DETAILS_TEST_ARITY(...) NT2_PP_DETAILS_APPLY(NT2_PP_DETAILS_TEST_ARITY_I, (__VA_ARGS__, 2, 1)) #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS(cond, x) NT2_PP_DETAILS_MAYBE_STRIP_PARENS_I(cond, x) #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_I(cond, x) BOOST_PP_CAT(NT2_PP_DETAILS_MAYBE_STRIP_PARENS_, cond)(x) #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_1(x) x #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2(x) NT2_PP_DETAILS_APPLY(NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I, x) #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__ #define NT2_PP_STRIP(x) NT2_PP_DETAILS_EVAL((NT2_PP_DETAILS_STRIP_PARENS_I x), x) //////////////////////////////////////////////////////////////////////////////// // Proto basic extends for template domain //////////////////////////////////////////////////////////////////////////////// #define BOOST_PROTO_BASIC_EXTENDS_TPL(Expr, Derived, Domain) \ BOOST_PROTO_BASIC_EXTENDS_( NT2_PP_STRIP(Expr) \ , NT2_PP_STRIP(Derived) \ , NT2_PP_STRIP(Domain) \ ) \ typedef void proto_is_aggregate_; \ typedef typename NT2_PP_STRIP(Domain)::proto_generator proto_generator; \ namespace nt2 { namespace simd { //////////////////////////////////////////////////////////////////////////////// // Some forward //////////////////////////////////////////////////////////////////////////////// template< class Type, class Cardinal> struct domain; template< class Expression , class Type , class Cardinal , class Dummy = boost::proto::is_proto_expr > struct expression; //////////////////////////////////////////////////////////////////////////////// // Fake data to be stored in terminals //////////////////////////////////////////////////////////////////////////////// template<class T, class C> struct data {}; //////////////////////////////////////////////////////////////////////////////// // the template grammar //////////////////////////////////////////////////////////////////////////////// template<class T, class C> struct grammar : boost::proto ::or_ < boost::proto::terminal< data<T,C> > , boost::proto:: and_< boost::proto:: nary_expr < boost::proto::_ , boost::proto::vararg< grammar<T,C> > > , boost::proto:: not_< boost::proto::or_ < boost::proto:: address_of< grammar<T,C> > , boost::proto:: dereference< grammar<T,C> > , boost::proto:: comma < grammar<T,C> , grammar<T,C> > > > > > {}; //////////////////////////////////////////////////////////////////////////////// // The template generator //////////////////////////////////////////////////////////////////////////////// template<class Type,class Cardinal> struct generator { template<class Sig> struct result; template<class This, class Expr> struct result<This(Expr)> { typedef expression<Expr,Type,Cardinal> type; }; template<class Expr> expression<Expr,Type,Cardinal> const operator()(Expr const &xpr) const { expression<Expr,Type,Cardinal> const that = {xpr}; return that; } }; //////////////////////////////////////////////////////////////////////////////// // simd expression //////////////////////////////////////////////////////////////////////////////// template<class Expr,class Type,class Cardinal, class Dummy> struct expression { //////////////////////////////////////////////////////////////////////////// // Make this a proto expression //////////////////////////////////////////////////////////////////////////// typedef domain<Type,Cardinal> domain_type; typedef expression<Expr,Type,Cardinal,Dummy> self_type; BOOST_PROTO_BASIC_EXTENDS_TPL(Expr, self_type, domain_type) }; //////////////////////////////////////////////////////////////////////////////// // simd expression domain //////////////////////////////////////////////////////////////////////////////// template<class Type,class Cardinal> struct domain : boost::proto::domain< generator<Type,Cardinal> , grammar<Type,Cardinal> > { }; template<class Type,std::size_t Cardinal,class BP = boost::proto::is_proto_expr> struct pack { //////////////////////////////////////////////////////////////////////////// // Data holder of pack terminals //////////////////////////////////////////////////////////////////////////// typedef data<Type,boost::mpl::size_t<Cardinal> > data_type; //////////////////////////////////////////////////////////////////////////// // Make pack a POD proto expression //////////////////////////////////////////////////////////////////////////// BOOST_PROTO_BASIC_EXTENDS_TPL ( typename boost::proto::terminal<data_type>::type , (pack<Type,Cardinal>) , (simd::domain<Type, boost::mpl::size_t<Cardinal> >) ) }; // The exponent bits function turn pack<float,4> into pack<int,4> struct exponentbits_ {}; boost::proto:: result_of::make_expr< exponentbits_, domain<int,boost::mpl::size_t<4> >,pack<float,4> const& >::type exponentbits( pack<float,4> const& x) { return boost::proto:: make_expr< exponentbits_, domain<int,boost::mpl::size_t<4> > >( boost::cref(x) ); } } } int main() { nt2::simd::pack<float,4> x; nt2::simd::pack<int,4> y; boost::proto::display_expr(x+x); // ok //boost::proto::display_expr(y+x); // not ok -- expected boost::proto::display_expr(exponentbits(x)); boost::proto::display_expr(exponentbits(x)+y); // not ok - unexpected. // fails with: /* * /Users/joelfalcou/nt2/sandbox/proto.cpp:161:46: * error: no match for 'operator+' in * 'nt2::simd::exponentbits(((const nt2::simd::pack<float, 4ul>&)((const nt2::simd::pack<float, 4ul>*)(& x)))) + y' */ }
Private
[
?
]
Run code
Submit