phoenix使い始め。(lazy_make_shared)
phoenixが強力らしいので使ってみることにした。
main.cpp
#include <iostream> #include <vector> #include <boost/spirit/home/phoenix.hpp> #include <pstade/oven/algorithm.hpp> #include <pstade/oven/initial_values.hpp> #include "./lazy_make_shared.hpp" class A { public: A(int n) : n_(n) { std::cout << "created(" << n << ")" << std::endl; } friend std::ostream & operator<< (std::ostream &os, A const &a) { return os << "A(" << a.n_ << ")"; } private: int n_; }; int main() { namespace oven = pstade::oven; namespace phx = boost::phoenix; std::vector<int> const vs = oven::initial_values(1, 3, 5, 7); std::vector< boost::shared_ptr<A> > as; std::cout << "create A" << std::endl; oven::for_each( vs, phx::push_back( phx::ref(as), hwm::lazy_make_shared<A>::get()(phx::arg_names::arg1) ) ); std::cout << "display A" << std::endl; oven::for_each(as, std::cout << *phx::arg_names::arg1 << std::endl); }
create A created(1) created(3) created(5) created(7) display A A(1) A(3) A(5) A(7)
lazy_make_shared.hpp
#ifndef HWM_LAZY_MAKE_SHARED_HPP #define HWM_LAZY_MAKE_SHARED_HPP #define HWM_LAZY_MAKE_SHARED_ARG_LIMIT 10 #include <boost/spirit/home/phoenix/function/function.hpp> #include "./lazy_make_shared_impl.hpp" namespace hwm { template<typename T> struct lazy_make_shared { typedef boost::phoenix::function< lazy_make_shared_impl<T> > value_type; static value_type const get() { return lazy_make_shared_impl<T>(); } }; } //namespace hwm #endif //HWM_LAZY_MAKE_SHARED_HPP
lazy_make_shared_impl.hpp
#if !BOOST_PP_IS_ITERATING #ifndef HWM_LAZY_MAKE_SHARED_IMPL_HPP #define HWM_LAZY_MAKE_SHARED_IMPL_HPP #include <boost/make_shared.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/iteration/iterate.hpp> namespace hwm { template<typename T> struct lazy_make_shared_impl { struct unused_type {}; #define HWM_LOCAL_DEF_UNUSED(_, N, data) \ typename BOOST_PP_CAT(unused, N) = unused_type template< BOOST_PP_ENUM(HWM_LAZY_MAKE_SHARED_ARG_LIMIT, HWM_LOCAL_DEF_UNUSED, _) > struct result { typedef boost::shared_ptr<T> type; }; typedef typename result<>::type result_type; #undef HWM_LOCAL_DEF_UNUSED #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, HWM_LAZY_MAKE_SHARED_ARG_LIMIT, "lazy_make_shared_impl.hpp")) #include BOOST_PP_ITERATE() }; } //namespace hwm #endif //HWM_LAZY_MAKE_SHARED_IMPL_HPP #else //iterating #define N BOOST_PP_ITERATION() #if N == 0 typename result<>::type operator()() const { return boost::make_shared<T>(); } #else template< BOOST_PP_ENUM_PARAMS(N, typename Arg) > typename result<BOOST_PP_ENUM_PARAMS(N, Arg)>::type operator() (BOOST_PP_ENUM_BINARY_PARAMS(N, Arg, const &arg)) const { return boost::make_shared<T>( BOOST_PP_ENUM_PARAMS(N, arg) ); } #endif #endif //N == 0 #endif //iterating
・・・と、ここまで書いてから、
oven::for_each(
vs,
phx::push_back(
phx::ref(as),
//hwm::lazy_make_shared<A>::get()(phx::arg_names::arg1)
phx::construct< boost::shared_ptr<A> >(
phx::new_<A>(phx::arg_names::arg1)
)
)
);
これで良いじゃんということに気づいて(´・ω・`)