diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/phoenix/example | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/phoenix/example')
19 files changed, 1355 insertions, 0 deletions
diff --git a/src/boost/libs/phoenix/example/adapted_echo_server.cpp b/src/boost/libs/phoenix/example/adapted_echo_server.cpp new file mode 100644 index 00000000..71ea5276 --- /dev/null +++ b/src/boost/libs/phoenix/example/adapted_echo_server.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/all_odds.cpp b/src/boost/libs/phoenix/example/all_odds.cpp new file mode 100644 index 00000000..66a846c1 --- /dev/null +++ b/src/boost/libs/phoenix/example/all_odds.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/arguments.cpp b/src/boost/libs/phoenix/example/arguments.cpp new file mode 100644 index 00000000..25ec58d3 --- /dev/null +++ b/src/boost/libs/phoenix/example/arguments.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/bind_goose.cpp b/src/boost/libs/phoenix/example/bind_goose.cpp new file mode 100644 index 00000000..66c51994 --- /dev/null +++ b/src/boost/libs/phoenix/example/bind_goose.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/callback.cpp b/src/boost/libs/phoenix/example/callback.cpp new file mode 100644 index 00000000..dba286ba --- /dev/null +++ b/src/boost/libs/phoenix/example/callback.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/container_actor.cpp b/src/boost/libs/phoenix/example/container_actor.cpp new file mode 100644 index 00000000..a784ee2d --- /dev/null +++ b/src/boost/libs/phoenix/example/container_actor.cpp @@ -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"; +} diff --git a/src/boost/libs/phoenix/example/define_expression.cpp b/src/boost/libs/phoenix/example/define_expression.cpp new file mode 100644 index 00000000..f2744bd7 --- /dev/null +++ b/src/boost/libs/phoenix/example/define_expression.cpp @@ -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"; +} + + diff --git a/src/boost/libs/phoenix/example/factorial.cpp b/src/boost/libs/phoenix/example/factorial.cpp new file mode 100644 index 00000000..619a5f05 --- /dev/null +++ b/src/boost/libs/phoenix/example/factorial.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/find_if.cpp b/src/boost/libs/phoenix/example/find_if.cpp new file mode 100644 index 00000000..476e331b --- /dev/null +++ b/src/boost/libs/phoenix/example/find_if.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/function.cpp b/src/boost/libs/phoenix/example/function.cpp new file mode 100644 index 00000000..ecf97634 --- /dev/null +++ b/src/boost/libs/phoenix/example/function.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/generator.cpp b/src/boost/libs/phoenix/example/generator.cpp new file mode 100644 index 00000000..e3120683 --- /dev/null +++ b/src/boost/libs/phoenix/example/generator.cpp @@ -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); +} diff --git a/src/boost/libs/phoenix/example/generator2.cpp b/src/boost/libs/phoenix/example/generator2.cpp new file mode 100644 index 00000000..aef2f986 --- /dev/null +++ b/src/boost/libs/phoenix/example/generator2.cpp @@ -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)); +} diff --git a/src/boost/libs/phoenix/example/identity_transform.cpp b/src/boost/libs/phoenix/example/identity_transform.cpp new file mode 100644 index 00000000..471bec09 --- /dev/null +++ b/src/boost/libs/phoenix/example/identity_transform.cpp @@ -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); +} diff --git a/src/boost/libs/phoenix/example/if.cpp b/src/boost/libs/phoenix/example/if.cpp new file mode 100644 index 00000000..8ed95a74 --- /dev/null +++ b/src/boost/libs/phoenix/example/if.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/invert.cpp b/src/boost/libs/phoenix/example/invert.cpp new file mode 100644 index 00000000..3c5e64f0 --- /dev/null +++ b/src/boost/libs/phoenix/example/invert.cpp @@ -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)); +} + diff --git a/src/boost/libs/phoenix/example/lambda.cpp b/src/boost/libs/phoenix/example/lambda.cpp new file mode 100644 index 00000000..adfd798e --- /dev/null +++ b/src/boost/libs/phoenix/example/lambda.cpp @@ -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; +} + diff --git a/src/boost/libs/phoenix/example/parallel_for.cpp b/src/boost/libs/phoenix/example/parallel_for.cpp new file mode 100644 index 00000000..1fc11d14 --- /dev/null +++ b/src/boost/libs/phoenix/example/parallel_for.cpp @@ -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); + } +} diff --git a/src/boost/libs/phoenix/example/references.cpp b/src/boost/libs/phoenix/example/references.cpp new file mode 100644 index 00000000..26d35ca0 --- /dev/null +++ b/src/boost/libs/phoenix/example/references.cpp @@ -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; +} diff --git a/src/boost/libs/phoenix/example/values.cpp b/src/boost/libs/phoenix/example/values.cpp new file mode 100644 index 00000000..ec58e29e --- /dev/null +++ b/src/boost/libs/phoenix/example/values.cpp @@ -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; +} |