libpnicore
container_utils.hpp
1 //
2 // (c) Copyright 2013 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 libpnicore. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // ============================================================================
20 //
21 // Created on: Nov 07, 2013
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 
25 #pragma once
26 
27 #include <iostream>
28 #include <sstream>
29 #include <tuple>
30 #include "../error/exceptions.hpp"
31 #include "sfinae_macros.hpp"
32 
33 namespace pni{
34 namespace core{
35 
36 
58  template<typename CTYPE>
60  {
62  typedef CTYPE container_type;
64  typedef typename CTYPE::value_type value_type;
65 
66  //---------------------------------------------------------------------
71 
80  static container_type create(size_t n,
86  value_type default_value=value_type())
87  {
88  container_type c(n);
89  std::fill(c.begin(),c.end(),default_value);
90  return c;
91  }
92 
93  //---------------------------------------------------------------------
98 
108  template<
117  typename ITERT,
119  >
120  static container_type create(ITERT begin,ITERT end)
121  {
122  container_type c(std::distance(begin,end));
123  std::copy(begin,end,c.begin());
124  return c;
125  }
126 
127  //---------------------------------------------------------------------
133 
143  template<
148  typename OCTYPE,
149  typename = enable_if<not_t<is_pod<OCTYPE>>>
150  >
151  static container_type create(const OCTYPE &o)
152  {
153  container_type c(o.size());
154  std::copy(o.begin(),o.end(),c.begin());
155  return c;
156  }
157 
158  //---------------------------------------------------------------------
165 
174  template<typename T>
179  static container_type create(const std::initializer_list<T> &list)
180  {
181  container_type c(list.size());
182  std::copy(list.begin(),list.end(),c.begin());
183  return c;
184  }
185  };
186 
187  //-------------------------------------------------------------------------
201  template<
202  typename T,
203  size_t N
204  >
205  struct container_utils<std::array<T,N>>
206  {
208  typedef std::array<T,N> container_type;
210  typedef T value_type;
211 
212  //---------------------------------------------------------------------
221 
228  static container_type create(size_t n,
235  value_type default_value=value_type())
236  {
237  if(n!=N)
238  {
239  std::stringstream message;
240  message<<"Number of elements ("<<n<<") not supported by ";
241  message<<"array type which has ("<<N<<")!";
242  throw size_mismatch_error(EXCEPTION_RECORD,message.str());
243  }
244 
245  container_type v;
246  std::fill(v.begin(),v.end(),default_value);
247  return v;
248  }
249 
250  //---------------------------------------------------------------------
259 
267  template<
275  typename ITERT,
276  typename = enable_if<or_t<
278  >>
279  >
280  static container_type create(ITERT begin,ITERT end)
281  {
282  if(N!=std::distance(begin,end))
283  {
284  std::stringstream message;
285  message<<"Iterators span ("<<std::distance(begin,end)<<")";
286  message<<" only ("<<N<<") supported by the array type!";
287  throw size_mismatch_error(EXCEPTION_RECORD,message.str());
288  }
289 
290  container_type v;
291  std::copy(begin,end,v.begin());
292  return v;
293  }
294 
295  //---------------------------------------------------------------------
302 
309  template<
316  typename OCTYPE,
317  typename = enable_if<not_t<is_pod<OCTYPE>>>
318  >
319  static container_type create(const OCTYPE &o)
320  {
321  if(o.size() != N)
322  {
323  std::stringstream message;
324  message<<"Original container has ("<<o.size()<<") elements, ";
325  message<<"array supports only ("<<N<<")!";
326  throw size_mismatch_error(EXCEPTION_RECORD,message.str());
327  }
328 
329  container_type v;
330  std::copy(o.begin(),o.end(),v.begin());
331  return v;
332  }
333 
334  //---------------------------------------------------------------------
343  static container_type create(const std::array<T,N> &c)
344  {
345  return c;
346  }
347 
348  //---------------------------------------------------------------------
357 
364  template<typename ET>
371  static container_type create(const std::initializer_list<ET> &list)
372  {
373  if(list.size()!=N)
374  {
375  std::stringstream message;
376  message<<"Initializer list has ("<<list.size()<<") elements, ";
377  message<<"array supports only ("<<N<<")!";
378  throw size_mismatch_error(EXCEPTION_RECORD,message.str());
379  }
380 
381  container_type v;
382  std::copy(list.begin(),list.end(),v.begin());
383  return v;
384  }
385  };
386 
387  //=========================================================================
388  // implementation of a variadic function template to check the size of a set
389  // of containers passed as variadic input arguments
390  //=========================================================================
391 
392  //-------------------------------------------------------------------------
393  template<typename STYPE>
394  bool check_size(STYPE)
395  {
396  return true;
397  }
398 
399  //-------------------------------------------------------------------------
400  template<
401  typename STYPE,
402  typename CTYPE,
403  typename ...CTYPES
404  >
405  bool check_size(STYPE s,const CTYPE &c,const CTYPES& ...cs)
406  {
407  return s!=c.size()?false:check_size(c.size(),cs...);
408  }
409 
410  //-------------------------------------------------------------------------
418 
433  template<
441  typename CTYPE,
442  typename ...CTYPES
443  >
444  bool check_equal_size(const CTYPE &c,const CTYPES& ...cs)
445  {
446  return check_size(c.size(),cs...);
447  }
448 
449 
450 
451 //end of namespace
452 }
453 }
static container_type create(size_t n, value_type default_value=value_type())
create container of given size
Definition: container_utils.hpp:85
static container_type create(const std::initializer_list< ET > &list)
initialize std::array from an initializer list
Definition: container_utils.hpp:371
Size mismatch error.
Definition: exceptions.hpp:399
std::is_pointer< T > is_ptr
shortcut for std::is_pointer
Definition: sfinae_macros.hpp:122
#define EXCEPTION_RECORD
macro creating an instance of ExceptionRecord
Definition: exceptions.hpp:48
type erasure array types
Definition: array.hpp:74
logical not
Definition: sfinae_macros.hpp:97
STL namespace.
CTYPE::value_type value_type
the element type of the container
Definition: container_utils.hpp:64
container utility
Definition: container_utils.hpp:59
static container_type create(ITERT begin, ITERT end)
create container from a range
Definition: container_utils.hpp:120
Definition: add_op.hpp:29
invoke< std::enable_if< C::value >> enable_if
shortcut for std::enable_if
Definition: sfinae_macros.hpp:108
bool check_equal_size(const CTYPE &c, const CTYPES &...cs)
check container sizes
Definition: container_utils.hpp:444
static container_type create(const OCTYPE &o)
initialize std::array from a container
Definition: container_utils.hpp:319
or type
Definition: sfinae_macros.hpp:60
static container_type create(const std::initializer_list< T > &list)
create from initializer list
Definition: container_utils.hpp:179
CTYPE container_type
type of the container
Definition: container_utils.hpp:62
static container_type create(const std::array< T, N > &c)
create from array
Definition: container_utils.hpp:343
static container_type create(ITERT begin, ITERT end)
initialize std::array from an iterator range
Definition: container_utils.hpp:280
std::array< T, N > container_type
type of the container
Definition: container_utils.hpp:208
T value_type
value type of the container
Definition: container_utils.hpp:210
static container_type create(const OCTYPE &o)
create from another container
Definition: container_utils.hpp:151