libpnicore
value_ref.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: Jan 11, 2013
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 #pragma once
25 #include<iostream>
26 #include<memory>
27 
28 #include "../error/exceptions.hpp"
29 #include "../types/types.hpp"
30 #include "value_holder.hpp"
31 #include "utils.hpp"
32 
33 namespace pni{
34 namespace core{
35 
36  class value;
37 
43  class value_ref
44  {
45  private:
47  typedef std::unique_ptr<value_holder_interface> pointer_type;
48 
49  //----------------------------------------------------------------
60  void _check_pointer(const exception_record &r) const;
61 
62  //----------------------------------------------------------------
73  void _check_type(type_id_t tid,const exception_record &r) const;
74 
75  //----------------------------------------------------------------
89  template<
90  typename T,
91  typename S
92  >
93  T _get() const
94  {
95  return get_value<T,S>(get_holder_ptr<ref_type<S>>(_ptr));
96  }
97 
98  //----------------------------------------------------------------
111  template<
112  typename S,
113  typename T
114  >
115  void _set(const T& v) const
116  {
117  return set_value<S,T>(get_holder_ptr<ref_type<S>>(_ptr),v);
118  }
119 
121  pointer_type _ptr;
122  public:
123  //================constructors and destructor======================
127  value_ref();
128 
129  //-----------------------------------------------------------------
134 
140  template<typename T>
144  explicit value_ref(std::reference_wrapper<T> v):
145  _ptr(new value_holder<std::reference_wrapper<T> >(v))
146  {}
147 
148  //-----------------------------------------------------------------
152  value_ref(const value_ref &o);
153 
154  //==================assignment operators===========================
171  template<typename T> value_ref &operator=(const T &v);
172 
173  //----------------------------------------------------------------
192  value_ref &operator=(const value &v);
193 
194  //-----------------------------------------------------------------
196  // we should remove this - makes not really sense. We can
197  // always destroy the reference and create a new one (could we?)
198  value_ref &operator=(const value_ref &o);
199 
200  //-----------------------------------------------------------------
207  operator value () const;
208 
209  //-----------------------------------------------------------------
225  template<typename T> T as() const;
226 
227  //-----------------------------------------------------------------
236  type_id_t type_id() const;
237 
238  };
239 
240  //======================implementation of template members=================
241  template<typename T> T value_ref::as() const
242  {
243  //check if the reference points to something
245 
246  type_id_t tid = type_id();
247  switch(tid)
248  {
249  case type_id_t::UINT8: return _get<T,uint8>();
250  case type_id_t::INT8: return _get<T,int8>();
251  case type_id_t::UINT16: return _get<T,uint16>();
252  case type_id_t::INT16: return _get<T,int16>();
253  case type_id_t::UINT32: return _get<T,uint32>();
254  case type_id_t::INT32: return _get<T,int32>();
255  case type_id_t::UINT64: return _get<T,uint64>();
256  case type_id_t::INT64: return _get<T,int64>();
257  case type_id_t::FLOAT32: return _get<T,float32>();
258  case type_id_t::FLOAT64: return _get<T,float64>();
259  case type_id_t::FLOAT128: return _get<T,float128>();
260  case type_id_t::COMPLEX32: return _get<T,complex32>();
261  case type_id_t::COMPLEX64: return _get<T,complex64>();
262  case type_id_t::COMPLEX128: return _get<T,complex128>();
263  case type_id_t::BINARY: return _get<T,binary>();
264  case type_id_t::STRING: return _get<T,string>();
265  case type_id_t::BOOL: return _get<T,bool_t>();
266  default:
268  "The reference points to an object of unkown type!");
269  }
270 
271  }
272 
273  //-------------------------------------------------------------------------
274  template<typename T> value_ref &value_ref::operator=(const T &v)
275  {
277 
278  type_id_t tid = type_id();
279 
280  switch(tid)
281  {
282  case type_id_t::UINT8: _set<uint8>(v); break;
283  case type_id_t::INT8: _set<int8>(v); break;
284  case type_id_t::UINT16: _set<uint16>(v); break;
285  case type_id_t::INT16: _set<int16>(v); break;
286  case type_id_t::UINT32: _set<uint32>(v); break;
287  case type_id_t::INT32: _set<int32>(v); break;
288  case type_id_t::UINT64: _set<uint64>(v); break;
289  case type_id_t::INT64: _set<int64>(v); break;
290  case type_id_t::FLOAT32: _set<float32>(v); break;
291  case type_id_t::FLOAT64: _set<float64>(v); break;
292  case type_id_t::FLOAT128: _set<float128>(v); break;
293  case type_id_t::COMPLEX32: _set<complex32>(v); break;
294  case type_id_t::COMPLEX64: _set<complex64>(v); break;
295  case type_id_t::COMPLEX128: _set<complex128>(v); break;
296  case type_id_t::BINARY: _set<binary>(v); break;
297  case type_id_t::STRING: _set<string>(v); break;
298  case type_id_t::BOOL: _set<bool_t>(v); break;
299  default:
301  "The reference points to an object of unknown type!");
302  }
303 
304  return *this;
305  }
306 
307  //------------------------------------------------------------------------
322  value to_value(const value_ref &v);
323 
324 //end of namespace
325 }
326 }
327 
32Bit IEEE floating point
exception record
Definition: exceptions.hpp:90
#define EXCEPTION_RECORD
macro creating an instance of ExceptionRecord
Definition: exceptions.hpp:48
T _get() const
return value
Definition: value_ref.hpp:93
data type error
Definition: exceptions.hpp:544
signed 8Bit integer
STL namespace.
unsigned 32Bit integer
void _set(const T &v) const
set value
Definition: value_ref.hpp:115
unsigned 64Bit integer
unsigned 16Bit integer
128Bit IEEE floating point complex
64Bit IEEE floating point
std::unique_ptr< value_holder_interface > pointer_type
internal pointer type used to hold the reference instance
Definition: value_ref.hpp:47
Definition: add_op.hpp:29
unsigned 8Bit integer
void _check_pointer(const exception_record &r) const
throw exception
implementation of the holder interface
Definition: value_holder.hpp:174
32Bit IEEE floating point complex
128Bit IEEE floating point
value_ref(std::reference_wrapper< T > v)
template constructor from value
Definition: value_ref.hpp:144
pointer_type _ptr
pointer holding the value stored
Definition: value_ref.hpp:121
type_id_t type_id() const
get type id
type_id_t
type codes for PNI data types
Definition: types/types.hpp:148
value_ref & operator=(const T &v)
assign value to the variable
Definition: value_ref.hpp:274
64Bit IEEE floating point complex
type erasure for references to POD data
Definition: value_ref.hpp:43
type erasure for POD data
Definition: value.hpp:46
signed 64Bit integer
void _check_type(type_id_t tid, const exception_record &r) const
check type
signed 32Bit integer
value_ref()
default constructor
value to_value(const value_ref &v)
conversion function to value
signed 16Bit integer
T as() const
get the referenced value
Definition: value_ref.hpp:241