Scarab  v2.9.0
Project 8 C++ Utility Library
param_binding_helpers.cc
Go to the documentation of this file.
1 #include <algorithm> //for std::replace on string
2 
3 #include "param.hh"
4 #include "error.hh"
5 
6 #include "pybind11/pybind11.h"
7 #include "pybind11/pytypes.h"
8 
9 
10 namespace scarab_pybind
11 {
12  scarab::param_ptr_t to_param( const pybind11::object& an_object, bool hyphenate_keys=false )
13  {
14  using namespace pybind11;
15  if( isinstance< none >( an_object ) )
16  {
17  return scarab::param_ptr_t( new scarab::param() );
18  }
19  else if( isinstance< bool_ >( an_object ) )
20  {
21  return scarab::param_ptr_t( new scarab::param_value( static_cast< const bool_& >(an_object) ) );
22  }
23  else if( isinstance< int_ >( an_object ) )
24  {
25  return scarab::param_ptr_t( new scarab::param_value( (int64_t)static_cast< const int_& >(an_object) ) );
26  }
27  else if( isinstance< float_ >( an_object ) )
28  {
29  return scarab::param_ptr_t( new scarab::param_value( (double)static_cast< const float_& >(an_object) ) );
30  }
31  else if( isinstance< str >( an_object ) )
32  {
33  return scarab::param_ptr_t( new scarab::param_value( static_cast< const str& >(an_object) ) );
34  }
35  else if( isinstance< list >( an_object ) )
36  {
37  scarab::param_ptr_t the_return( new scarab::param_array() );
38  scarab::param_array& the_return_arr = the_return->as_array();
39  for( auto an_item = an_object.begin(); an_item != an_object.end(); ++an_item )
40  {
41  the_return_arr.push_back( to_param( reinterpret_borrow< object >( *an_item ) ) );
42  }
43  return the_return;
44  }
45  else if( isinstance< dict >( an_object ) )
46  {
47  scarab::param_ptr_t the_return( new scarab::param_node() );
48  scarab::param_node& the_return_arr = the_return->as_node();
49  const dict& a_dict = static_cast< const dict& >( an_object );
50  for( auto an_item = a_dict.begin(); an_item != a_dict.end(); ++an_item )
51  {
52  if( ! isinstance< str >(an_item->first) || ! isinstance< object >(an_item->second) )
53  {
54  throw scarab::error() << "Cannot convert dict to param";
55  }
56  std::string new_key = pybind11::str(an_item->first);
57  if ( hyphenate_keys )
58  {
59  std::replace( new_key.begin(), new_key.end(), '_', '-' );
60  }
61  the_return_arr.add( new_key, to_param( static_cast< const object& >(an_item->second) ) );
62  }
63  return the_return;
64  }
65  throw scarab::error() << "Unknown python type cannot be converted to param";
66  }
67 
68  pybind11::object to_python( const scarab::param& a_param, bool underscore_keys = false )
69  {
70  if (a_param.is_null())
71  {
72  return pybind11::none();
73  }
74  else if (a_param.is_value())
75  {
76  const scarab::param_value& this_value = a_param.as_value();
77  pybind11::object to_return;
78  if (this_value.is_bool()) to_return = pybind11::cast(this_value.as_bool());
79  else if (this_value.is_uint()) to_return = pybind11::cast(this_value.as_uint());
80  else if (this_value.is_int()) to_return = pybind11::cast(this_value.as_int());
81  else if (this_value.is_double()) to_return = pybind11::cast(this_value.as_double());
82  else if (this_value.is_string()) to_return = pybind11::cast(this_value.as_string());
83  return to_return;
84  }
85  else if (a_param.is_array())
86  {
87  const scarab::param_array& this_array = a_param.as_array();
88  pybind11::list to_return;
89  for (scarab::param_array_const_iterator an_item=this_array.begin(); an_item != this_array.end(); ++an_item)
90  {
91  to_return.append( to_python( *an_item ) );
92  }
93  return std::move(to_return);
94  }
95  else if (a_param.is_node())
96  {
97  const scarab::param_node& this_node = a_param.as_node();
98  pybind11::dict to_return;
99  for (scarab::param_node_const_iterator an_item=this_node.begin(); an_item != this_node.end(); ++an_item)
100  {
101  std::string new_key = an_item.name();
102  if ( underscore_keys )
103  {
104  std::replace( new_key.begin(), new_key.end(), '-', '_' );
105  }
106  to_return[ new_key.c_str() ] = to_python( *an_item );
107  }
108  return std::move(to_return);
109  }
110  throw scarab::error() << "Unknown param type cannot be converted to Python";
111  }
112 
113 } /* namespace scarab_pybind */
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)
scarab::param_ptr_t to_param(const pybind11::object &an_object, bool hyphenate_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
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