proteus  1.8.1
C/C++/Fortran libraries
ArgumentsDict.h
Go to the documentation of this file.
1 #ifndef ARGUMENTSDICT_H
2 #define ARGUMENTSDICT_H
3 
4 #include <map>
5 #include <stdexcept>
6 #include <string>
7 #include "xtensor-python/pyarray.hpp"
8 #include "xtensor/xio.hpp"
9 
10 namespace proteus
11 {
12 
13  /****************
14  * throwing_map *
15  ****************/
16 
17  // Special map that behaves like a standard map except for
18  // - operator[] which throws instead of inserting a default
19  // value when a key is not found
20  // - insert and insert_or_assign which always move the key
21  // and the value. This allows to keep pyarrays synchronized
22  // with the numpy arrays they refer to, while avoiding code
23  // duplication for array of scalars (because insert_or_assign
24  // is not available in C++14)
25  template <class K, class T>
26  class throwing_map : private std::map<K, T>
27  {
28  public:
29 
30  using base_type = std::map<K, T>;
31  using key_type = typename base_type::key_type;
32  using mapped_type = typename base_type::mapped_type;
33  using value_type = typename base_type::value_type;
34  using reference = typename base_type::reference;
35  using const_reference = typename base_type::const_reference;
36  using pointer = typename base_type::pointer;
37  using const_pointer = typename base_type::const_pointer;
38  using size_type = typename base_type::size_type;
39  using difference_type = typename base_type::difference_type;
40  using iterator = typename base_type::iterator;
41  using const_iterator = typename base_type::const_iterator;
42 
43  using base_type::empty;
44  using base_type::find;
45  using base_type::emplace;
46 
47  using base_type::begin;
48  using base_type::end;
49  using base_type::cbegin;
50  using base_type::cend;
51 
52  // Throws if k is not in the map
54 
55  std::pair<iterator, bool> insert(value_type&&);
56  std::pair<iterator, bool> insert_or_assign(key_type&& k, mapped_type&& v);
57  };
58 
59  /******************
60  * arguments_dict *
61  ******************/
62 
63  template <class K, class T>
65 
66  template <class K, class T>
68 
70  {
75 
76  template <class T>
77  xt::pyarray<T>& array(const std::string& key);
78 
79  template <class T>
80  T& scalar(const std::string& key);
81 
82  private:
83 
84  template <class D1, class D2>
85  typename D1::mapped_type& find_element(const std::string& key,
86  D1& expected_dict,
87  const D2& other_dict,
88  const std::string& expected_type,
89  const std::string& other_type);
90 
91  template <class D>
92  std::string get_additional_error_msg(const std::string& key,
93  const D& d,
94  const std::string& asked_type,
95  const std::string& tried_type) const;
96  };
97 
98  /*******************************
99  * throwing_map implementation *
100  *******************************/
101 
102  namespace detail
103  {
104  template <class T>
105  inline std::string key_error_messagei(const T& key)
106  {
107  return key_error_message(std::to_string(key));
108  }
109 
110  inline std::string key_error_message(const std::string& key)
111  {
112  return std::string("key ") + key + std::string(" not found");
113  }
114  }
115 
116  template <class K, class T>
118  {
119  auto it = this->find(k);
120  if(it == end())
121  {
122  throw std::runtime_error(detail::key_error_message(k));
123  }
124  return it->second;
125  }
126 
127  template <class K, class T>
128  inline auto throwing_map<K, T>::insert(value_type&& v) -> std::pair<iterator, bool>
129  {
130  return base_type::insert(std::move(v));
131  }
132 
133  template <class K, class T>
134  inline auto throwing_map<K, T>::insert_or_assign(key_type&& k, mapped_type&& v) -> std::pair<iterator, bool>
135  {
136  auto it = base_type::find(k);
137  if(it == base_type::end())
138  {
139  return base_type::emplace(k, std::move(v));
140  }
141  else
142  {
143  it->second = std::move(v);
144  return std::make_pair(it, false);
145  }
146  }
147 
148  /*********************************
149  * arguments_dict implementation *
150  *********************************/
151 
152  template <>
153  inline xt::pyarray<double>& arguments_dict::array<double>(const std::string& key)
154  {
155  return find_element(key, m_darray, m_iarray, "pyarray<double>", "pyarray<int>");
156  }
157 
158  template <>
159  inline xt::pyarray<int>& arguments_dict::array<int>(const std::string& key)
160  {
161  return find_element(key, m_iarray, m_darray, "pyarray<int>", "pyarray<double>");
162  }
163 
164  template <>
165  inline double& arguments_dict::scalar<double>(const std::string& key)
166  {
167  return find_element(key, m_dscalar, m_iscalar, "double scalar", "int scalar");
168  }
169 
170  template <>
171  inline int& arguments_dict::scalar<int>(const std::string& key)
172  {
173  return find_element(key, m_iscalar, m_dscalar, "int scalar", "double scalar");
174  }
175 
176  template <class D1, class D2>
177  typename D1::mapped_type& arguments_dict::find_element(const std::string& key,
178  D1& expected_dict,
179  const D2& other_dict,
180  const std::string& expected_type,
181  const std::string& other_type)
182  {
183  try
184  {
185  return expected_dict[key];
186  }
187  catch(std::runtime_error& e)
188  {
189  throw std::runtime_error(e.what()
190  + get_additional_error_msg(key, other_dict, expected_type, other_type));
191  }
192  }
193 
194  template <class D>
195  std::string arguments_dict::get_additional_error_msg(const std::string& key,
196  const D& d,
197  const std::string& asked_type,
198  const std::string& tried_type) const
199  {
200  auto it = d.find(key);
201  if (it == d.cend())
202  {
203  return " in any of the internal dicts";
204  }
205  else
206  {
207  return " in dict of " + asked_type + " but found in dict of " + tried_type;
208  }
209  }
210 }
211 
212 #endif
213 
proteus::throwing_map< std::string, double >::const_reference
typename base_type::const_reference const_reference
Definition: ArgumentsDict.h:35
proteus::throwing_map< std::string, double >::size_type
typename base_type::size_type size_type
Definition: ArgumentsDict.h:38
proteus::throwing_map::operator[]
mapped_type & operator[](const key_type &k)
Definition: ArgumentsDict.h:117
proteus::throwing_map< std::string, double >::pointer
typename base_type::pointer pointer
Definition: ArgumentsDict.h:36
proteus::arguments_dict::m_iscalar
scalar_dict< std::string, int > m_iscalar
Definition: ArgumentsDict.h:74
D
#define D(x, y)
Definition: jf.h:9
proteus::throwing_map< std::string, double >::key_type
typename base_type::key_type key_type
Definition: ArgumentsDict.h:31
proteus::throwing_map< std::string, double >::const_pointer
typename base_type::const_pointer const_pointer
Definition: ArgumentsDict.h:37
proteus::throwing_map::insert
std::pair< iterator, bool > insert(value_type &&)
Definition: ArgumentsDict.h:128
proteus::arguments_dict::scalar
T & scalar(const std::string &key)
proteus::arguments_dict::array
xt::pyarray< T > & array(const std::string &key)
proteus::arguments_dict::m_darray
pyarray_dict< std::string, double > m_darray
Definition: ArgumentsDict.h:71
v
Double v
Definition: Headers.h:95
proteus::throwing_map< std::string, double >::base_type
std::map< std::string, double > base_type
Definition: ArgumentsDict.h:30
proteus::throwing_map::insert_or_assign
std::pair< iterator, bool > insert_or_assign(key_type &&k, mapped_type &&v)
Definition: ArgumentsDict.h:134
T
Double T
Definition: Headers.h:87
proteus::throwing_map< std::string, double >::value_type
typename base_type::value_type value_type
Definition: ArgumentsDict.h:33
proteus::throwing_map< std::string, double >::iterator
typename base_type::iterator iterator
Definition: ArgumentsDict.h:40
proteus::arguments_dict::m_iarray
pyarray_dict< std::string, int > m_iarray
Definition: ArgumentsDict.h:72
proteus::throwing_map< std::string, double >::difference_type
typename base_type::difference_type difference_type
Definition: ArgumentsDict.h:39
proteus::throwing_map< std::string, double >::reference
typename base_type::reference reference
Definition: ArgumentsDict.h:34
proteus::arguments_dict::m_dscalar
scalar_dict< std::string, double > m_dscalar
Definition: ArgumentsDict.h:73
proteus::detail::key_error_messagei
std::string key_error_messagei(const T &key)
Definition: ArgumentsDict.h:105
proteus::detail::key_error_message
std::string key_error_message(const std::string &key)
Definition: ArgumentsDict.h:110
proteus::throwing_map< std::string, double >::mapped_type
typename base_type::mapped_type mapped_type
Definition: ArgumentsDict.h:32
proteus::throwing_map< std::string, double >::const_iterator
typename base_type::const_iterator const_iterator
Definition: ArgumentsDict.h:41
proteus
Definition: ADR.h:17
proteus::arguments_dict
Definition: ArgumentsDict.h:70
proteus::throwing_map
Definition: ArgumentsDict.h:27