libpnicore
exception_utils.hpp
1 //
2 // (c) Copyright 2011 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpnicore.
5 //
6 // libpnicore is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpnicore is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with lipniutils. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // ============================================================================
20 //
21 // Created on: May 23, 2012
22 // Author: Eugen Wintersberger
23 //
24 //
25 #pragma once
26 
27 #include <vector>
28 #include <iostream>
29 #include <algorithm>
30 #include <boost/units/detail/utility.hpp>
31 
32 #include "../error/exceptions.hpp"
33 #include "../utilities/service.hpp"
34 
35 namespace pni{
36 namespace core{
37 
49  template<typename VTYPE>
50  void print_vector(std::ostream &o,const VTYPE &v)
51  {
52  o<<"( ";
53  for(auto x: v) o<<x<<" ";
54  o<<")";
55  }
56 
57  //=====================Exception related helper functions==================
73  template<
74  typename A,
75  typename B
76  >
77  bool check_equal_size(const A &a,const B &b)
78  {
79  return a.size() == b.size();
80  }
81 
82  //-------------------------------------------------------------------------
100  template<
101  typename A,
102  typename B
103  >
104  void check_equal_size(const A &a,const B &b,const exception_record &i)
105  {
106  if(!check_equal_size(a,b))
107  {
108  std::stringstream ss;
109  ss<<"Size of "<<boost::units::detail::demangle(typeid(A).name())<<" (";
110  ss<<a.size()<<") ";
111  ss<<"does not match size of "<<boost::units::detail::demangle(typeid(B).name())<<" (";
112  ss<<b.size()<<")!";
113  throw size_mismatch_error(i,string(ss.str()));
114  }
115  }
116 
117  //-------------------------------------------------------------------------
130  bool check_index_in_dim(size_t index,size_t dimsize);
131 
132  //-------------------------------------------------------------------------
146  void check_index_in_dim(size_t index,size_t dimsize,
147  const exception_record &i);
148 
149  //-------------------------------------------------------------------------
163  template<
164  typename ITYPE,
165  typename STYPE
166  >
167  bool check_indexes(const ITYPE &index,const STYPE &shape)
168  {
169  if(!check_equal_size(index,shape)) return false;
170 
171  auto iiter = index.begin();
172  auto siter = shape.begin();
173 
174  for(;iiter!=index.end();++iiter,++siter)
175  if(*iiter>=*siter) return false;
176 
177  return true;
178  }
179 
180  //-------------------------------------------------------------------------
199  template<
200  typename ITYPE,
201  typename STYPE
202  >
203  void check_indexes(const ITYPE &index,const STYPE &shape,
204  const exception_record &record)
205  {
206  //check size - if it does not match throw an exception
207  if(!check_equal_size(index,shape))
208  {
209  std::stringstream ss;
210  ss<<"Rank of index vector ("<<index.size()<<") does not match ";
211  ss<<"the rank of the shape vector ("<<shape.size()<<")!";
212  throw shape_mismatch_error(record,ss.str());
213  }
214 
215  //if sizes of the vectors match check the individual ranges.
216  if(!check_indexes(index,shape))
217  {
218  std::stringstream ss;
219  ss<<"Indexes ";
220  print_vector(ss,index);
221  ss<<" do not match shape ";
222  print_vector(ss,shape);
223  ss<<std::endl;
224 
225  throw index_error(record,ss.str());
226  }
227 
228  }
229 
230  //-------------------------------------------------------------------------
244  template<
245  typename A,
246  typename B
247  >
248  bool check_equal_rank(const A &a,const B &b)
249  {
250  return a.rank() == b.rank();
251  }
252 
253  //-------------------------------------------------------------------------
267  template<
268  typename A,
269  typename B
270  >
271  void check_equal_rank(const A &a,const B &b,const exception_record &i)
272  {
273  if(!check_equal_rank(a,b))
274  {
275  std::stringstream ss;
276  ss<<"Rank of "<<boost::units::detail::demangle(typeid(a).name())<<" (";
277  ss<<a.rank()<<") does not match that of ";
278  ss<<boost::units::detail::demangle(typeid(b).name())<<" (";
279  ss<<b.rank()<<")!";
280  throw shape_mismatch_error(i,ss.str());
281  }
282  }
283 
284  //-------------------------------------------------------------------------
290  template<
291  typename A,
292  typename B
293  >
294  bool check_equal_shape(const A &a,const B &b)
295  {
296  //check if the sizes match
297  if(!check_equal_size(a,b)) return false;
298  if(!check_equal_rank(a,b)) return false;
299 
300  auto sa = a.template shape<std::vector<size_t> >();
301  auto sb = b.template shape<std::vector<size_t> >();
302 
303  if(!std::equal(sa.begin(),sa.end(),sb.begin()))
304  return false;
305 
306  return true;
307  }
308 
309 
310  //-------------------------------------------------------------------------
326  template<typename A,typename B>
327  void check_equal_shape(const A &a,const B &b,const exception_record &i)
328  {
329  check_equal_size(a,b,i);
330  check_equal_rank(a,b,i);
331 
332  if(!check_equal_shape(a,b))
333  {
334  std::stringstream ss;
335  ss<<"Shape of "<<boost::units::detail::demangle(typeid(a).name())<<" (";
336  ss<<a.size()<<") does not match that of ";
337  ss<<boost::units::detail::demangle(typeid(b).name())<<" (";
338  ss<<b.size()<<")!";
339  throw shape_mismatch_error(i,ss.str());
340  }
341 
342  }
343 
344  //-------------------------------------------------------------------------
355  template<typename OTYPE>
356  void check_allocation_state(const OTYPE &o,const exception_record &i)
357  {
358  if(!o.size())
359  {
360  std::stringstream ss;
361  ss<<"Instance of "<<boost::units::detail::demangle(typeid(OTYPE).name());
362  ss<<" not allocated!";
363  throw memory_not_allocated_error(i,ss.str());
364  }
365  }
366 
367  //-------------------------------------------------------------------------
377  template<typename T>
378  void check_ptr_state(const T *ptr,const exception_record &i)
379  {
380  if(!ptr)
381  {
382  std::stringstream ss;
383  ss<<"Pointer is nullptr!";
384  throw memory_not_allocated_error(i,ss.str());
385  }
386  }
387 
388 
389 
390 //end of namespace
391 }
392 }
Size mismatch error.
Definition: exceptions.hpp:399
exception record
Definition: exceptions.hpp:90
void check_indexes(const ITYPE &index, const STYPE &shape, const exception_record &record)
check indexes
Definition: exception_utils.hpp:203
void print_vector(std::ostream &o, const VTYPE &v)
print vector content
Definition: exception_utils.hpp:50
void check_ptr_state(const T *ptr, const exception_record &i)
check pointer state
Definition: exception_utils.hpp:378
Shape mismatch error.
Definition: exceptions.hpp:360
void check_allocation_state(const OTYPE &o, const exception_record &i)
check allocation state
Definition: exception_utils.hpp:356
index error
Definition: exceptions.hpp:437
Definition: add_op.hpp:29
void check_index_in_dim(size_t index, size_t dimsize, const exception_record &i)
check index in dim
void check_equal_rank(const A &a, const B &b, const exception_record &i)
check equal rank
Definition: exception_utils.hpp:271
memory not allocated error
Definition: exceptions.hpp:321
void check_equal_size(const A &a, const B &b, const exception_record &i)
check if two objects have different size
Definition: exception_utils.hpp:104
void check_equal_shape(const A &a, const B &b, const exception_record &i)
check shape equality
Definition: exception_utils.hpp:327