early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,111 @@
//
// Copyright (c) 2011 Thomas Heller
//
// 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)
//
#include <cstdlib>
#include <iostream>
#define BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
#include <boost/phoenix.hpp>
#include <boost/asio.hpp>
namespace phx = boost::phoenix;
using boost::phoenix::ref;
BOOST_PHOENIX_ADAPT_FUNCTION(void, read, boost::asio::async_read, 4)
BOOST_PHOENIX_ADAPT_FUNCTION(void, write, boost::asio::async_write, 3)
BOOST_PHOENIX_ADAPT_FUNCTION(boost::asio::mutable_buffers_1, buffer, boost::asio::buffer, 2)
template <typename Acceptor, typename Socket, typename Handler>
void accept_impl(Acceptor & acceptor, Socket & socket, Handler const & handler)
{
acceptor.async_accept(socket, handler);
}
BOOST_PHOENIX_ADAPT_FUNCTION(void, accept, accept_impl, 3)
typedef phx::expression::local_variable<struct action_key>::type action;
#include <boost/function.hpp>
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: async_tcp_echo_server <port>\n";
return 1;
}
phx::lambda_type lambda;
phx::arg_names::_1_type _1;
boost::asio::io_service io_service;
boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), std::atoi(argv[1])));
boost::asio::ip::tcp::socket socket(io_service);
std::size_t const max_length = 1024;
char buf[max_length];
std::cout << "server starting...\n";
boost::function<void(boost::system::error_code const &)> accept_handler;
phx::expression::argument<1>::type _error;
phx::expression::argument<2>::type _length;
action _action;
BOOST_AUTO(
create_handler
, (lambda(_action = lambda[_1])
[
if_(!_error)
[
bind(_action, ref(socket), ref(buf), _error, _length)
]
.else_
[
bind(&boost::asio::ip::tcp::socket::close, ref(socket))
, accept(ref(acceptor), ref(socket), phx::ref(accept_handler))
]
])
);
boost::function<void(boost::system::error_code const &, std::size_t)> read_handler;
boost::function<void(boost::system::error_code const &, std::size_t)> write_handler;
accept_handler =
if_(!_error)
[
read(ref(socket), buffer(ref(buf), max_length), boost::asio::transfer_at_least(1), phx::ref(read_handler))
];
{
phx::expression::argument<1>::type _socket;
phx::expression::argument<2>::type _buf;
phx::expression::argument<3>::type _error;
phx::expression::argument<4>::type _length;
read_handler = create_handler(
write(_socket, buffer(_buf, _length), phx::ref(write_handler))
);
write_handler = create_handler(
read(_socket, buffer(_buf, max_length), boost::asio::transfer_at_least(1), phx::ref(read_handler))
);
}
acceptor.async_accept(
socket
, accept_handler
);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}

View File

@@ -0,0 +1,35 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/statement.hpp>
int
main()
{
using boost::phoenix::if_;
using boost::phoenix::arg_names::arg1;
int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
std::vector<int> c(init, init + 10);
typedef std::vector<int>::iterator iterator;
// Print all odd contents of an stl container c
std::for_each(c.begin(), c.end(),
if_(arg1 % 2 == 1)
[
std::cout << arg1 << ' '
]
);
std::cout << std::endl;
return 0;
}

View File

@@ -0,0 +1,21 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <boost/phoenix/core.hpp>
int
main()
{
using boost::phoenix::arg_names::arg1;
using boost::phoenix::arg_names::arg2;
int i = 3;
char const* s = "Hello World";
std::cout << arg1(i) << std::endl; // prints 3
std::cout << arg2(i, s) << std::endl; // prints "Hello World"
return 0;
}

View File

@@ -0,0 +1,144 @@
/*=============================================================================
For Boost Bind:
Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd.
Copyright (c) 2001 David Abrahams
Copyright (c) 2005 Peter Dimov
For Boost Phoenix:
Copyright (c) 2001-2010 Joel de Guzman
Copyright (c) 2010 Thomas Heller
For the example:
Copyright (c) 2011 Paul Heil
Copyright (c) 2015 John Fletcher
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)
==============================================================================*/
// bind_goose.cpp
// This example is based on code by Paul Heil to be found here:
// http://www.codeproject.com/Tips/248492/How-does-boost-phoenix-improve-boost-bind
//
// Show different ways of using boost bind and phoenix to handle deletion.
//
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/bind.hpp>
#include <boost/phoenix/operator/comparison.hpp>
#include <boost/phoenix/stl/algorithm/transformation.hpp>
#include <functional>
#include <string>
#include <vector>
////////////////////////////////////////////
// Set up the list here
////////////////////////////////////////////
std::vector< std::string > make_list() {
std::vector< std::string > list;
list.push_back( "duck" );
list.push_back( "duck" );
list.push_back( "goose" );
return list;
}
//////////////////////////////////////////////
// First example using standard library only
//////////////////////////////////////////////
bool IsGoose( const std::string& s )
{
return s == "goose";
}
void delete_value1(std::vector< std::string > &list )
{
list.erase( std::remove_if( list.begin(), list.end(), IsGoose ), list.end() );
}
void out_string(const std::string &s)
{
std::cout << s << std::endl;
}
void show_list1( const std::vector< std::string > &list )
{
std::for_each(list.begin(), list.end(), out_string);
}
//////////////////////////////////////////////
// Second example using boost bind
//////////////////////////////////////////////
bool isValue(const std::string &s1, const std::string &s2)
{
return s1==s2;
}
void delete_value2(std::vector< std::string > &list, const std::string & value)
{
list.erase(
std::remove_if(
list.begin(),
list.end(),
boost::bind(
isValue, // &isValue works as well.
_1, // Boost.Bind placeholder
boost::cref( value ) ) ),
list.end() );
}
///////////////////////////////////////////////////////
// Third example using boost phoenix for the comparison
///////////////////////////////////////////////////////
namespace phx = boost::phoenix;
using phx::placeholders::arg1;
using phx::placeholders::arg2;
void delete_value3(std::vector< std::string > &list, const std::string & value)
{
list.erase( std::remove_if(
list.begin(),
list.end(),
// This needs header boost/phoenix/operator/comparison.
// arg1 is a Boost.Phoenix placeholder.
arg1 == phx::cref( value ) ),
list.end() );
}
//////////////////////////////////////////////////////////////
// Third example using boost phoenix for the algorithm as well
//////////////////////////////////////////////////////////////
void delete_value4(std::vector< std::string > &list, const std::string & value)
{
// This need header boost/phoenix/stl/algorithm/transformation
list.erase( phx::remove_if( arg1, arg2 )
( list, arg1 == phx::cref( value ) ),
list.end() );
}
int main() {
std::cout << "--------------------------------" << std::endl;
std::cout << "Delete the goose examples." << std::endl;
std::cout << "--------------------------------" << std::endl;
std::string value = "goose";
std::vector< std::string > list1 = make_list();
delete_value1(list1);
show_list1(list1);
std::cout << "--------------------------------" << std::endl;
std::vector< std::string > list2 = make_list();
delete_value2(list2,value);
show_list1(list2);
std::cout << "--------------------------------" << std::endl;
std::vector< std::string > list3 = make_list();
delete_value3(list3,value);
show_list1(list3);
std::cout << "--------------------------------" << std::endl;
std::vector< std::string > list4 = make_list();
delete_value4(list4,value);
show_list1(list4);
std::cout << "--------------------------------" << std::endl;
return 0;
}

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <boost/phoenix/core.hpp>
template <typename F>
void print(F f)
{
std::cout << f() << std::endl;
}
int
main()
{
using boost::phoenix::val;
print(val(3));
print(val("Hello World"));
return 0;
}

View File

@@ -0,0 +1,117 @@
/*==============================================================================
Copyright (c) 2005-2010 Joel de Guzman
Copyright (c) 2010 Thomas Heller
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)
==============================================================================*/
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/function.hpp>
#include <boost/phoenix/stl/container.hpp>
#include <boost/phoenix/stl/algorithm.hpp>
#include <vector>
#include <iostream>
namespace phoenix = boost::phoenix;
using phoenix::actor;
using phoenix::function;
using phoenix::arg_names::arg1;
struct size_impl
{
// result_of protocol:
template <typename Sig>
struct result;
template <typename This, typename Container>
struct result<This(Container)>
{
// Note, remove reference here, because Container can be anything
typedef typename boost::remove_reference<Container>::type container_type;
// The result will be size_type
typedef typename container_type::size_type type;
};
template <typename Container>
typename result<size_impl(Container const&)>::type
operator()(Container const& container) const
{
return container.size();
}
};
template <typename Expr>
struct container_actor
: actor<Expr>
{
typedef actor<Expr> base_type;
typedef container_actor<Expr> that_type;
container_actor( base_type const& base = base_type() )
: base_type( base ) {}
typename phoenix::expression::function<phoenix::stl::begin, that_type>::type const
begin() const
{
return phoenix::begin(*this);
}
typename phoenix::expression::function<phoenix::stl::end, that_type>::type const
end() const
{
return phoenix::end(*this);
}
typename phoenix::expression::function<size_impl, that_type>::type const
size() const
{
function<size_impl> const f = size_impl();
return f(*this);
}
typename phoenix::expression::function<phoenix::stl::max_size, that_type>::type const
max_size() const
{
return phoenix::max_size(*this);
}
typename phoenix::expression::function<phoenix::stl::empty, that_type>::type const
empty() const
{
return phoenix::empty(*this);
}
template <typename Container>
typename phoenix::expression::function<phoenix::impl::swap, that_type, Container>::type const
swap(actor<Container> const& expr) const
{
return phoenix::swap(*this, expr);
}
};
template <typename Expr>
container_actor<Expr> const
container( actor<Expr> const& expr )
{
return expr;
}
int main()
{
container_actor<phoenix::expression::argument<1>::type> const con1;
std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::cout << (container(arg1).size())(v) << " == " << v.size() << "\n";
std::cout << (con1.size())(v) << " == " << v.size() << "\n";
}

View File

@@ -0,0 +1,60 @@
/*==============================================================================
Copyright (c) 2005-2010 Joel de Guzman
Copyright (c) 2011 Thomas Heller
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)
==============================================================================*/
#include <boost/phoenix/core.hpp>
namespace phoenix = boost::phoenix;
namespace proto = boost::proto;
// define the expression
namespace expression
{
template <typename Lhs, typename Rhs>
struct plus
: phoenix::expr<proto::tag::plus, Lhs, Rhs>
{};
}
// extend the grammar, to recognice the expression
namespace boost { namespace phoenix {
template <>
struct meta_grammar::case_<proto::tag::plus>
: enable_rule<
::expression::plus<
meta_grammar
, meta_grammar
>
>
{};
}}
// build a generator
template <typename Lhs, typename Rhs>
typename expression::plus<Lhs, Rhs>::type
plus(Lhs const & lhs, Rhs const & rhs)
{
return expression::plus<Lhs, Rhs>::make(lhs, rhs);
}
#include <boost/proto/proto.hpp>
#include <iostream>
int main()
{
plus(6, 5);
proto::display_expr(plus(6, 5));
std::cout << plus(5, 6)() << "\n";
}

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2001-2003 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)
==============================================================================*/
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/function.hpp>
struct factorial_impl
{
template <typename Sig>
struct result;
template <typename This, typename Arg>
struct result<This(Arg)>
: result<This(Arg const &)>
{};
template <typename This, typename Arg>
struct result<This(Arg &)>
{
typedef Arg type;
};
template <typename Arg>
Arg operator()(Arg n) const
{
return (n <= 0) ? 1 : n * this->operator()(n-1);
}
};
int
main()
{
using boost::phoenix::arg_names::arg1;
boost::phoenix::function<factorial_impl> factorial;
int i = 4;
std::cout << factorial(i)() << std::endl;
std::cout << factorial(arg1)(i) << std::endl;
return 0;
}

View File

@@ -0,0 +1,28 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
int
main()
{
using boost::phoenix::arg_names::arg1;
int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
std::vector<int> c(init, init + 10);
typedef std::vector<int>::iterator iterator;
// Find the first odd number in container c
iterator it = std::find_if(c.begin(), c.end(), arg1 % 2 == 1);
if (it != c.end())
std::cout << *it << std::endl; // if found, print the result
return 0;
}

View File

@@ -0,0 +1,43 @@
/*=============================================================================
Copyright (c) 2001-2003 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)
==============================================================================*/
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/function.hpp>
using boost::phoenix::function;
struct is_odd_
{
typedef bool result_type;
template <typename Arg>
bool operator()(Arg arg1) const
{
return arg1 % 2 == 1;
}
};
function<is_odd_> is_odd;
int
main()
{
using boost::phoenix::arg_names::arg1;
int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
std::vector<int> c(init, init + 10);
typedef std::vector<int>::iterator iterator;
// Find the first odd number in container c
iterator it = std::find_if(c.begin(), c.end(), is_odd(arg1));
if (it != c.end())
std::cout << *it << std::endl; // if found, print the result
return 0;
}

View File

@@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2011 Thomas Heller
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)
==============================================================================*/
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix.hpp>
template <typename> struct wrap {};
int main()
{
using boost::phoenix::val;
using boost::phoenix::lambda;
using boost::phoenix::let;
using boost::phoenix::construct;
using boost::phoenix::placeholders::_1;
using boost::phoenix::local_names::_a;
int const n = 10;
std::vector<int> v1(n);
let(_a = construct<int>(0))
[
generate(_1, lambda(_a = ref(_a))[_a++])
, std::cout << val("result:\n")
, for_each(_1, lambda[std::cout << _1 << ' '])
, std::cout << val('\n')
](v1);
}

View File

@@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2011 Thomas Heller
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)
==============================================================================*/
#include <boost/phoenix.hpp>
#include <boost/typeof/typeof.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
using boost::phoenix::lambda;
using boost::phoenix::let;
using boost::phoenix::ref;
using boost::phoenix::construct;
using boost::phoenix::local_names::_a;
using boost::phoenix::arg_names::_1;
BOOST_AUTO(
generator
, (lambda
(
_a = val(_1)
)
[
std::cout << _a << " "
, _a++
] )
);
int i = 0;
std::vector<int> v(10);
std::for_each(v.begin(), v.end(), generator(0));
}

View File

@@ -0,0 +1,124 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <boost/phoenix.hpp>
#include <iostream>
#include <sstream>
namespace proto = boost::proto;
namespace phoenix = boost::phoenix;
template <typename Rule>
struct identity_transform;
struct identity_actions
{
template <typename Rule>
struct when : phoenix::call<identity_transform<Rule> > {};
};
template <>
struct identity_actions::when<phoenix::rule::argument>
: proto::call<
identity_transform<phoenix::rule::argument>(proto::_value, phoenix::_context)
> {};
template <>
struct identity_actions::when<phoenix::rule::terminal>
: proto::call<
identity_transform<phoenix::rule::terminal>(proto::_value, phoenix::_context)
> {};
template <>
struct identity_actions::when<phoenix::rule::custom_terminal>
: proto::lazy<
identity_transform<proto::_value>(proto::_value, phoenix::_context)
> {};
template <>
struct identity_transform<phoenix::rule::terminal>
{
typedef std::string result_type;
template <typename Terminal, typename Context>
std::string operator()(Terminal const & terminal, Context) const
{
std::stringstream ss;
ss << "val(" << terminal << ")";
return ss.str();
}
template <typename Context>
std::string operator()(char const * terminal, Context) const
{
std::stringstream ss;
ss << "val(\"" << terminal << "\")";
return ss.str();
}
};
template <typename T>
struct identity_transform<boost::reference_wrapper<T> >
{
typedef std::string result_type;
template <typename Terminal, typename Context>
std::string operator()(Terminal const & terminal, Context) const
{
std::stringstream ss;
ss << "ref(" << terminal << ")";
return ss.str();
}
template <int N, typename Context>
std::string operator()(boost::reference_wrapper<char const *> terminal, Context) const
{
std::stringstream ss;
ss << "ref(\"" << terminal << "\")";
return ss.str();
}
template <int N, typename Context>
std::string operator()(boost::reference_wrapper<char const [N]> terminal, Context) const
{
std::stringstream ss;
ss << "ref(\"" << terminal << "\")";
return ss.str();
}
};
template <>
struct identity_transform<phoenix::rule::argument>
{
typedef std::string result_type;
template <typename N, typename Context>
std::string operator()(N, Context) const
{
std::stringstream ss;
ss << "_" << N::value;
return ss.str();
}
};
template <typename Expr>
void identity(Expr const & expr)
{
std::cout << phoenix::eval(expr, phoenix::context(int(), identity_actions())) << "\n";
}
int main()
{
identity(phoenix::val(8));
identity(phoenix::val("8"));
identity(phoenix::ref("blubb"));
identity(phoenix::arg_names::_1);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/phoenix/statement.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/core.hpp>
int
main()
{
using boost::phoenix::if_;
using boost::phoenix::arg_names::arg1;
int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> v(init, init+10);
std::cout << std::dec;
int x = 0;
std::for_each(v.begin(), v.end(),
if_(arg1 > 5)
[
std::cout << arg1 << ", "
]
);
std::cout << std::endl;
return 0;
}

View File

@@ -0,0 +1,138 @@
/*==============================================================================
Copyright (c) 2005-2010 Joel de Guzman
Copyright (c) 2010 Thomas Heller
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)
==============================================================================*/
#include <boost/phoenix/phoenix.hpp>
#include <boost/proto/proto.hpp>
#include <boost/proto/debug.hpp>
namespace phoenix = boost::phoenix;
namespace proto = boost::proto;
using phoenix::evaluator;
#ifdef _MSC_VER
// redifining evaluator, this is because MSVC chokes on function types like:
// F(G(...))
#define evaluator(A0, A1) proto::call<phoenix::evaluator(A0, A1)>
#endif
struct invert_actions
{
template <typename Rule>
struct when
: proto::nary_expr<
proto::_
, proto::vararg<
proto::when<proto::_, evaluator(proto::_, phoenix::_context)>
>
>
{};
};
template <>
struct invert_actions::when<phoenix::rule::plus>
: proto::call<
phoenix::functional::make_minus(
evaluator(proto::_left, phoenix::_context)
, evaluator(proto::_right, phoenix::_context)
)
>
{};
template <>
struct invert_actions::when<phoenix::rule::minus>
: proto::call<
phoenix::functional::make_plus(
evaluator(proto::_left, phoenix::_context)
, evaluator(proto::_right, phoenix::_context)
)
>
{};
template <>
struct invert_actions::when<phoenix::rule::multiplies>
: proto::call<
phoenix::functional::make_divides(
evaluator(proto::_left, phoenix::_context)
, evaluator(proto::_right, phoenix::_context)
)
>
{};
template <>
struct invert_actions::when<phoenix::rule::divides>
: proto::call<
phoenix::functional::make_multiplies(
evaluator(proto::_left, phoenix::_context)
, evaluator(proto::_right, phoenix::_context)
)
>
{};
#ifdef _MSC_VER
#undef evaluator
#endif
template <typename Expr>
void print_expr(Expr const & expr)
{
std::cout << "before inversion:\n";
proto::display_expr(expr);
std::cout << "after inversion:\n";
proto::display_expr(
phoenix::eval(
expr
, phoenix::context(
phoenix::nothing
, invert_actions()
)
)
);
std::cout << "\n";
}
template <typename Expr>
typename
boost::phoenix::result_of::eval<
Expr const&
, phoenix::result_of::make_context<
phoenix::result_of::make_env<>::type
, invert_actions
>::type
>::type
invert(Expr const & expr)
{
return
phoenix::eval(
expr
, phoenix::make_context(
phoenix::make_env()
, invert_actions()
)
);
}
int main()
{
using phoenix::placeholders::_1;
using phoenix::placeholders::_2;
using phoenix::placeholders::_3;
using phoenix::placeholders::_4;
print_expr(_1);
print_expr(_1 + _2);
print_expr(_1 + _2 - _3);
print_expr(_1 * _2);
print_expr(_1 * _2 / _3);
print_expr(_1 * _2 + _3);
print_expr(_1 * _2 - _3);
print_expr(if_(_1 * _4)[_2 - _3]);
print_expr(_1 * invert(_2 - _3));
}

View File

@@ -0,0 +1,73 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/phoenix/scope.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/function.hpp>
namespace lazy_stuff
{
using boost::phoenix::function;
struct for_each_impl
{
typedef void result_type;
template <typename C, typename F>
void operator()(C& c, F f) const
{
std::for_each(c.begin(), c.end(), f);
}
};
function<for_each_impl> const for_each = for_each_impl();
struct push_back_impl
{
typedef void result_type;
template <typename C, typename T>
void operator()(C& c, T& x) const
{
c.push_back(x);
}
};
function<push_back_impl> const push_back = push_back_impl();
}
int
main()
{
{
using lazy_stuff::for_each;
using lazy_stuff::push_back;
using boost::phoenix::lambda;
using boost::phoenix::arg_names::arg1;
using boost::phoenix::arg_names::arg2;
using boost::phoenix::local_names::_a;
int x = 10;
std::vector<std::vector<int> > v(10);
for_each(arg1,
lambda(_a = arg2)
[
push_back(arg1, _a)
]
)
(v, x);
}
return 0;
}

View File

@@ -0,0 +1,245 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <boost/phoenix.hpp>
struct omp_for_eval
{
typedef void result_type;
template <typename Init, typename Cond, typename Step, typename Do, typename Context>
result_type
operator()(
Init const& init
, Cond const& cond
, Step const& step
, Do const& do_
, Context & ctx
) const
{
#pragma omp parallel
for(
boost::phoenix::eval(init, ctx);
boost::phoenix::eval(cond, ctx);
boost::phoenix::eval(step, ctx)
)
{
boost::phoenix::eval(do_, ctx);
}
}
};
////////////////////////////////////////////////////////////////////////////////
// Define new custom expression
BOOST_PHOENIX_DEFINE_EXPRESSION(
(omp_for)
, (boost::phoenix::meta_grammar) // Cond
(boost::phoenix::meta_grammar) // Init
(boost::phoenix::meta_grammar) // Step
(boost::phoenix::meta_grammar) // Do
)
namespace boost { namespace phoenix
{
template <>
struct default_actions::when< ::rule::omp_for>
: boost::phoenix::call< ::omp_for_eval>
{};
}}
template <typename Init, typename Cond, typename Step>
struct omp_for_gen
{
omp_for_gen(Init const& init, Cond const& cond, Step const& step)
: init(init), cond(cond), step(step) {}
template <typename Do>
typename result_of::make_omp_for<Init, Cond, Step, Do>::type const
operator[](Do const& do_) const
{
return make_omp_for(init, cond, step, do_);
}
Init init;
Cond cond;
Step step;
};
template <typename Init, typename Cond, typename Step>
inline
omp_for_gen<Init, Cond, Step> const
omp_for(Init const& init, Cond const& cond, Step const& step)
{
return omp_for_gen<Init, Cond, Step>(init, cond, step);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Define new evaluation scheme
struct parallel_actions
{
template <typename Rule>
struct when
: boost::phoenix::default_actions::when<Rule>
{};
};
template <>
struct parallel_actions::when<boost::phoenix::rule::for_>
: boost::phoenix::call<omp_for_eval>
{};
// Doing the same as actor<Expr>::operator
template <typename Expr, typename A0, typename A1, typename A2>
typename boost::phoenix::result_of::eval<
Expr const &
, typename boost::phoenix::result_of::make_context<
typename boost::phoenix::result_of::make_env<
Expr const *
, A0 &
, A1 &
, A2 &
>::type
, parallel_actions
>::type
>::type
parallel_eval(Expr & expr, A0 & a0, A1 & a1, A2 & a2)
{
Expr const * this_ = boost::addressof(expr);
return
boost::phoenix::eval(
expr
, boost::phoenix::make_context(
boost::phoenix::make_env(this_, a0, a1, a2)
, parallel_actions()
)
);
}
// changing evaluation mechanism on the fly
BOOST_PHOENIX_DEFINE_EXPRESSION(
(parallel)
, (boost::phoenix::meta_grammar)
)
namespace boost { namespace phoenix
{
template <>
struct default_actions::when< ::rule::parallel>
: proto::call<
evaluator(
proto::_child0
, functional::make_context(
_env
, parallel_actions()
)
, unused()//mpl::void_()
)
>
{};
}}
template <typename Expr>
typename result_of::make_parallel<Expr>::type
parallel(Expr const & expr)
{
return make_parallel(expr);
}
////////////////////////////////////////////////////////////////////////////////
#include <vector>
#include <iostream>
int main()
{
using boost::phoenix::arg_names::_1;
using boost::phoenix::arg_names::_2;
using boost::phoenix::arg_names::_3;
using boost::phoenix::local_names::_a;
using boost::phoenix::local_names::_b;
using boost::phoenix::local_names::_c;
using boost::phoenix::let;
using boost::phoenix::bind;
using boost::phoenix::lambda;
using boost::phoenix::nothing;
const int NUM = 1;
{
std::vector<int> a(NUM, 1);
std::vector<int> b(NUM, 2);
std::vector<int> c(NUM, 0);
(
let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
[
for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
[
*_c = *_a + *_b
]
]
, std::cout << accumulate(_3, 0) << "\n"
)(a, b, c);
}
{
std::vector<int> a(NUM, 1);
std::vector<int> b(NUM, 2);
std::vector<int> c(NUM, 0);
(
let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
[
omp_for(nothing, _a != end(_1), (++_a, ++_b, ++_c))
[
*_c = *_a + *_b
]
, std::cout << accumulate(_3, 0) << "\n"
]
)(a, b, c);
}
{
std::vector<int> a(NUM, 1);
std::vector<int> b(NUM, 2);
std::vector<int> c(NUM, 0);
parallel_eval(
let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
[
for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
[
*_c = *_a + *_b
]
, std::cout << accumulate(_3, 0) << "\n"
]
, a, b, c);
}
{
std::vector<int> a(NUM, 1);
std::vector<int> b(NUM, 2);
std::vector<int> c(NUM, 0);
(
let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
[
parallel(
for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
[
*_c = *_a + *_b
]
)
]
, std::cout << accumulate(_3, 0) << "\n"
)(a, b, c);
}
}

View File

@@ -0,0 +1,20 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <boost/phoenix/core.hpp>
int
main()
{
using boost::phoenix::ref;
int i = 3;
char const* s = "Hello World";
std::cout << ref(i)() << std::endl;
std::cout << ref(s)() << std::endl;
return 0;
}

View File

@@ -0,0 +1,18 @@
/*=============================================================================
Copyright (c) 2001-2007 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)
==============================================================================*/
#include <iostream>
#include <boost/phoenix/core.hpp>
int
main()
{
using boost::phoenix::val;
std::cout << val(3)() << std::endl;
std::cout << val("Hello World")() << std::endl;
return 0;
}