vdj_pipe
pipeline for processing DNA sequence data
step_builder_registry.hpp
Go to the documentation of this file.
1 
7 #ifndef STEP_BUILDER_REGISTRY_HPP_
8 #define STEP_BUILDER_REGISTRY_HPP_
9 #include <map>
10 #include <sstream>
11 #include "boost/function.hpp"
12 #include "boost/mpl/bind.hpp"
13 #include "boost/mpl/fold.hpp"
14 #include "boost/mpl/for_each.hpp"
15 #include "boost/mpl/insert.hpp"
16 #include "boost/mpl/quote.hpp"
17 #include "boost/mpl/set.hpp"
18 #include "boost/property_tree/json_parser.hpp"
19 #include "boost/property_tree/ptree.hpp"
20 
21 #include "vdj_pipe/exception.hpp"
24 
25 namespace vdj_pipe{
26 class Pipe_environment;
27 
28 namespace step{
29 
32 template<class Config> class Step_builder_registry {
33  typedef typename Config::processing_step step_variant;
34  typedef typename Config::value_map_access vm_access;
35 
36  typedef boost::function<
38  vm_access const&,
41  )
42  >
44 
45  typedef std::map<std::string, constructor_t> constructor_map_t;
46 
47  class Insert {
48  public:
49  explicit Insert(constructor_map_t& constr_map)
50  : cm_(&constr_map)
51  {}
52 
53  template<class M> static step_variant make(
54  vm_access const& vma,
57  ) {
58  return M::make(vma, pt, pe);
59  }
60 
61  template<class M> void operator()(M const&) const {
62  const typename constructor_map_t::value_type p(
63  M::name(),
64  &make<M>
65  );
66 
67  if( ! cm_->insert(p).second ) {
68  BOOST_THROW_EXCEPTION(
70  << base_exception::msg_t("duplicate step name")
71  << base_exception::str1_t(sanitize(M::name()))
72  );
73  }
74  }
75 
76  private:
77  mutable constructor_map_t* cm_;
78  };
79 
81  //make metafunction class
82  typedef boost::mpl::quote1<Find_maker> maker;
83 
84  //use "bind" to force placeholder evaluation
85  typedef typename boost::mpl::fold<
86  typename step_variant::types,
87  boost::mpl::set0<>,
88  boost::mpl::insert<
89  boost::mpl::_1,
90  boost::mpl::bind1<maker, boost::mpl::_2>
91  >
92  >::type maker_tl;
93 
94  Insert ins(constr_map_);
95  boost::mpl::for_each<maker_tl>(ins);
96  }
97 
98  step_variant make_impl(
99  std::string const& name,
100  vm_access const& vma,
101  boost::property_tree::ptree const& pt,
102  Pipe_environment& pe
103  ) const
104  {
105  typename constructor_map_t::const_iterator i = constr_map_.find(name);
106  if( i == constr_map_.end() ) BOOST_THROW_EXCEPTION(
108  << base_exception::msg_t("unsupported step")
110  );
111  return i->second(vma, pt, pe);
112  }
113 
114 public:
115 
116  static Step_builder_registry const& get() {
117  static const Step_builder_registry inst;
118  return inst;
119  }
120 
121  static step_variant make(
122  std::string const& name,
123  vm_access const& vma,
124  boost::property_tree::ptree const& pt,
125  Pipe_environment& pe
126  ) {
127  return get().make_impl(name, vma, pt, pe);
128  }
129 
130  static step_variant make(
131  vm_access const& vma,
132  boost::property_tree::ptree const& pt,
133  Pipe_environment& pe
134  ) {
135  if( pt.size() ) {
136  try{
137  if( pt.size() > 1 ) BOOST_THROW_EXCEPTION(
139  << base_exception::msg_t("multiple children found")
140  );
141  std::string const& name = pt.front().first;
142  return get().make_impl(name, vma, pt.front().second, pe);
143  } catch(boost::exception const&) {
144  std::stringstream ss;
145  write_json(ss, pt);
146  BOOST_THROW_EXCEPTION(
148  << base_exception::msg_t("error creating step")
149  << base_exception::str1_t(ss.str())
150  << base_exception::nested_t(boost::current_exception())
151  );
152  }
153  }
154 
155  return Blank_step();
156  }
157 
158 private:
159  constructor_map_t constr_map_;
160 };
161 
162 }//namespace step
163 }//namespace vdj_pipe
164 #endif /* STEP_BUILDER_REGISTRY_HPP_ */
step_variant make_impl(std::string const &name, vm_access const &vma, boost::property_tree::ptree const &pt, Pipe_environment &pe) const
Definition: step_builder_registry.hpp:98
Config::processing_step step_variant
Definition: step_builder_registry.hpp:33
std::map< std::string, constructor_t > constructor_map_t
Definition: step_builder_registry.hpp:45
static step_variant make(std::string const &name, vm_access const &vma, boost::property_tree::ptree const &pt, Pipe_environment &pe)
Definition: step_builder_registry.hpp:121
Insert(constructor_map_t &constr_map)
Definition: step_builder_registry.hpp:49
constructor_map_t * cm_
Definition: step_builder_registry.hpp:77
Definition: step_builder_registry.hpp:32
boost::function< step_variant(vm_access const &, boost::property_tree::ptree const &, Pipe_environment &) > constructor_t
Definition: step_builder_registry.hpp:43
Main namespace of vdj_pipe library.
Definition: keywords_variable.hpp:11
Definition: blank_step.hpp:20
boost::errinfo_nested_exception nested_t
Definition: exception.hpp:32
Definition: pipe_environment.hpp:26
void operator()(M const &) const
Definition: step_builder_registry.hpp:61
boost::error_info< struct errinfo_str1_, std::string > str1_t
Definition: exception.hpp:25
static step_variant make(vm_access const &vma, boost::property_tree::ptree const &pt, Pipe_environment &pe)
Definition: step_builder_registry.hpp:53
static step_variant make(vm_access const &vma, boost::property_tree::ptree const &pt, Pipe_environment &pe)
Definition: step_builder_registry.hpp:130
Definition: exception.hpp:23
boost::error_info< struct errinfo_message_, std::string > msg_t
Definition: exception.hpp:24
Step_builder_registry()
Definition: step_builder_registry.hpp:80
std::string sanitize(const char c)
Definition: sanitize_string.cpp:53
Config::value_map_access vm_access
Definition: step_builder_registry.hpp:34
Definition: step_builder_registry.hpp:47
constructor_map_t constr_map_
Definition: step_builder_registry.hpp:159
bpt::ptree ptree
Definition: processing_step_utils.hpp:19