MIRA
PythonSet.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Redistribution and modification of this code is strictly prohibited.
9  *
10  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
11  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
12  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
13  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
16  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
18  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
19  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
20  */
21 
32 #ifndef _MIRA_TOOLBOXES_PYTHON_PYTHONSET_H_
33 #define _MIRA_TOOLBOXES_PYTHON_PYTHONSET_H_
34 
35 #include <set>
36 #include <Python.h>
37 
39 
40 #include <error/Exceptions.h>
41 
42 namespace mira { namespace python {
43 
45 
46 template<typename type>
48  using SetType = std::set<type>;
49  static std::string str(const SetType& s) {
50  std::stringstream ss;
51  ss << '[';
52  bool first = true;
53  for(const auto& e : s) {
54  if (!first)
55  ss << ", ";
56  first = false;
57  ss << e;
58  if(ss.fail())
59  MIRA_THROW(XIO, "Failed to convert value into a string");
60  }
61  ss << ']';
62  return ss.str();
63  }
64 
65  static int size(const SetType& s) {
66  return s.size();
67  }
68 
69  static bool contains(const SetType& s, const type& key) {
70  return s.count(key)>0; // s.contains(key) available since C++20 only
71  }
72 
73  static void add(SetType& s, type key) {
74  s.insert(std::move(key));
75  }
76 
77  static void remove(SetType& s, const type& key) {
78  if (!contains(s, key))
79  MIRA_THROW(XAssertion, "Element not in set");
80  s.erase(key);
81  }
82 
83  static SetType set_union(const SetType& s, const SetType& other)
84  {
85  SetType result;
86  std::set_union(s.begin(), s.end(), other.begin(), other.end(),
87  inserter(result, result.begin()));
88  return result;
89  }
90 
91  static SetType set_intersection(const SetType& s, const SetType& other)
92  {
93  SetType result;
94  std::set_intersection(s.begin(), s.end(), other.begin(), other.end(),
95  inserter(result, result.begin()));
96  return result;
97  }
98 
99  static SetType set_difference(const SetType& s, const SetType& other)
100  {
101  SetType result;
102  std::set_difference(s.begin(), s.end(), other.begin(), other.end(),
103  inserter(result, result.begin()));
104  return result;
105  }
106 
107  static SetType set_symmetric_difference(const SetType& s, const SetType& other)
108  {
109  SetType result;
110  std::set_symmetric_difference(s.begin(), s.end(), other.begin(), other.end(),
111  inserter(result, result.begin()));
112  return result;
113  }
114 };
115 
116 inline void block_hashing(boost::python::object)
117 {
118  MIRA_THROW(XInvalidParameter, "objects of type python object are unhashable");
119 }
120 
121 #define MIRA_PYTHONCONNECTOR_PYTHONSET_FUNCTIONS(type, name, footerfunctions) \
122  class_<std::set<type> >(name, "mutable set") \
123  .def("__repr__", &PythonSetAccessor<type>::str) \
124  .def("__len__", &PythonSetAccessor<type>::size) \
125  .def("__contains__", &PythonSetAccessor<type>::contains) \
126  .def("add", &PythonSetAccessor<type>::add, "add element") \
127  .def("__delitem__", &PythonSetAccessor<type>::remove) \
128  .def("remove", &PythonSetAccessor<type>::remove, "remove element") \
129  .def("__iter__", boost::python::iterator<std::set<type> >()) \
130  .def("__hash__", block_hashing) \
131  .def("union", &PythonSetAccessor<type>::set_union, "set union") \
132  .def("__or__", &PythonSetAccessor<type>::set_union, "set union") \
133  .def("intersection", &PythonSetAccessor<type>::set_intersection, "set intersection") \
134  .def("__and__", &PythonSetAccessor<type>::set_intersection, "set intersection") \
135  .def("difference", &PythonSetAccessor<type>::set_difference, "elements not in second set") \
136  .def("__sub__", &PythonSetAccessor<type>::set_difference, "set difference") \
137  .def("symmetric_difference", &PythonSetAccessor<type>::set_symmetric_difference, "elements unique to either set") \
138  .def("__xor__", &PythonSetAccessor<type>::set_symmetric_difference, "symmetric set difference") \
139  footerfunctions;
140 
142 
143 }} // namespace
144 
145 #endif
static bool contains(const SetType &s, const type &key)
Definition: PythonSet.h:69
void block_hashing(boost::python::object)
Definition: PythonSet.h:116
#define MIRA_THROW(ex, msg)
static SetType set_symmetric_difference(const SetType &s, const SetType &other)
Definition: PythonSet.h:107
static SetType set_union(const SetType &s, const SetType &other)
Definition: PythonSet.h:83
static void add(SetType &s, type key)
Definition: PythonSet.h:73
PropertyHint type(const std::string &t)
static SetType set_intersection(const SetType &s, const SetType &other)
Definition: PythonSet.h:91
static SetType set_difference(const SetType &s, const SetType &other)
Definition: PythonSet.h:99
Include this instead of boost/python.hpp to reduce compile time warning spam from Boost internal inco...
static std::string str(const SetType &s)
Definition: PythonSet.h:49
std::set< type > SetType
Definition: PythonSet.h:48
static int size(const SetType &s)
Definition: PythonSet.h:65
Definition: PythonSet.h:47