Scarab  v2.11.1
Project 8 C++ Utility Library
param_binding_helpers.hh
Go to the documentation of this file.
1 /*
2  * param_binding_helpers.hh
3  *
4  * Created on: Jan 23, 2020
5  * Author: N. Oblath, L. Gladstone, B.H. LaRoque
6  */
7 
8 #ifndef PARAM_BINDING_HELPERS_HH_
9 #define PARAM_BINDING_HELPERS_HH_
10 
11 #include <algorithm> //for std::replace on string
12 
13 #include "param.hh"
14 #include "error.hh"
15 
16 #include "pybind11/pybind11.h"
17 #include "pybind11/pytypes.h"
18 
19 
20 namespace scarab_pybind
21 {
22 
23  scarab::param_ptr_t to_param( const pybind11::object& an_object, bool hyphenate_keys=false )
24  {
25  using namespace pybind11;
26  if( isinstance< none >( an_object ) )
27  {
28  return scarab::param_ptr_t( new scarab::param() );
29  }
30  else if( isinstance< bool_ >( an_object ) )
31  {
32  return scarab::param_ptr_t( new scarab::param_value( static_cast< const bool_& >(an_object) ) );
33  }
34  else if( isinstance< int_ >( an_object ) )
35  {
36  return scarab::param_ptr_t( new scarab::param_value( (int64_t)static_cast< const int_& >(an_object) ) );
37  }
38  else if( isinstance< float_ >( an_object ) )
39  {
40  return scarab::param_ptr_t( new scarab::param_value( (double)static_cast< const float_& >(an_object) ) );
41  }
42  else if( isinstance< str >( an_object ) )
43  {
44  return scarab::param_ptr_t( new scarab::param_value( static_cast< const str& >(an_object) ) );
45  }
46  else if( isinstance< list >( an_object ) )
47  {
48  scarab::param_ptr_t the_return( new scarab::param_array() );
49  scarab::param_array& the_return_arr = the_return->as_array();
50  for( auto an_item = an_object.begin(); an_item != an_object.end(); ++an_item )
51  {
52  the_return_arr.push_back( to_param( reinterpret_borrow< object >( *an_item ) ) );
53  }
54  return the_return;
55  }
56  else if( isinstance< dict >( an_object ) )
57  {
58  scarab::param_ptr_t the_return( new scarab::param_node() );
59  scarab::param_node& the_return_arr = the_return->as_node();
60  const dict& a_dict = static_cast< const dict& >( an_object );
61  for( auto an_item = a_dict.begin(); an_item != a_dict.end(); ++an_item )
62  {
63  if( ! isinstance< str >(an_item->first) || ! isinstance< object >(an_item->second) )
64  {
65  throw scarab::error() << "Cannot convert dict to param";
66  }
67  std::string new_key = pybind11::str(an_item->first);
68  if ( hyphenate_keys )
69  {
70  std::replace( new_key.begin(), new_key.end(), '_', '-' );
71  }
72  the_return_arr.add( new_key, to_param( static_cast< const object& >(an_item->second) ) );
73  }
74  return the_return;
75  }
76  throw scarab::error() << "Unknown python type cannot be converted to param";
77  };
78 
79  pybind11::object to_python( const scarab::param& a_param, bool underscore_keys = false )
80  {
81  if (a_param.is_null())
82  {
83  return pybind11::none();
84  }
85  else if (a_param.is_value())
86  {
87  const scarab::param_value& this_value = a_param.as_value();
88  pybind11::object to_return;
89  if (this_value.is_bool()) to_return = pybind11::cast(this_value.as_bool());
90  else if (this_value.is_uint()) to_return = pybind11::cast(this_value.as_uint());
91  else if (this_value.is_int()) to_return = pybind11::cast(this_value.as_int());
92  else if (this_value.is_double()) to_return = pybind11::cast(this_value.as_double());
93  else if (this_value.is_string()) to_return = pybind11::cast(this_value.as_string());
94  return to_return;
95  }
96  else if (a_param.is_array())
97  {
98  const scarab::param_array& this_array = a_param.as_array();
99  pybind11::list to_return;
100  for (scarab::param_array_const_iterator an_item=this_array.begin(); an_item != this_array.end(); ++an_item)
101  {
102  to_return.append( to_python( *an_item ) );
103  }
104  return std::move(to_return);
105  }
106  else if (a_param.is_node())
107  {
108  const scarab::param_node& this_node = a_param.as_node();
109  pybind11::dict to_return;
110  for (scarab::param_node_const_iterator an_item=this_node.begin(); an_item != this_node.end(); ++an_item)
111  {
112  std::string new_key = an_item.name();
113  if ( underscore_keys )
114  {
115  std::replace( new_key.begin(), new_key.end(), '-', '_' );
116  }
117  to_return[ new_key.c_str() ] = to_python( *an_item );
118  }
119  return std::move(to_return);
120  }
121  throw scarab::error() << "Unknown param type cannot be converted to Python";
122  };
123 
124 } /* namespace scarab_pybind */
125 #endif /* PARAM_BINDING_HLEPERS_HH_ */
int64_t as_int() const
Definition: param_value.hh:522
bool is_bool() const
Definition: param_value.hh:487
iterator end() const
Return a sentinel which ends iteration.
Definition: pytypes.h:1403
virtual bool is_value() const
bool isinstance< object >(handle obj)
Definition: pytypes.h:374
pybind11::object to_python(const scarab::param &a_param, bool underscore_keys=false)
iterator begin()
Definition: param_node.hh:328
glibc defines I as a macro which breaks things, e.g., boost template names
Definition: attr.h:15
boost::indirect_iterator< param_array_contents::const_iterator, const param > param_array_const_iterator
Definition: param_array.hh:29
bool is_uint() const
Definition: param_value.hh:492
double as_double() const
Definition: param_value.hh:527
virtual bool is_null() const
detail::dict_iterator end() const
Definition: pytypes.h:1226
bool as_bool() const
Definition: param_value.hh:512
param_value & as_value()
virtual bool is_array() const
iterator begin() const
Definition: pytypes.h:1402
scarab::param_ptr_t to_param(const pybind11::object &an_object, bool hyphenate_keys=false)
bool is_double() const
Definition: param_value.hh:502
virtual bool is_node() const
std::unique_ptr< param > param_ptr_t
Definition: param_base.hh:23
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
Definition: cast.h:1685
bool is_string() const
Definition: param_value.hh:507
return os str()
param_node & as_node()
uint64_t as_uint() const
Definition: param_value.hh:517
param_array & as_array()
T cast(const handle &handle)
Definition: cast.h:1659
void push_back(const param &a_value)
Definition: param_array.hh:238
bool add(const std::string &a_name, const param &a_value)
Definition: param_node.hh:228
bool is_int() const
Definition: param_value.hh:497
std::string as_string() const
Definition: param_value.hh:532
detail::dict_iterator begin() const
Definition: pytypes.h:1225