RefleX
Build DDS Applications in Modern C++ without IDL
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
safe_typecode.h
Go to the documentation of this file.
1 /*********************************************************************************************
2 (c) 2005-2014 Copyright, Real-Time Innovations, Inc. All rights reserved.
3 RTI grants Licensee a license to use, modify, compile, and create derivative works
4 of the Software. Licensee has the right to distribute object form only for use with RTI
5 products. The Software is provided "as is", with no warranty of any type, including
6 any warranty for fitness for any purpose. RTI is under no obligation to maintain or
7 support the Software. RTI shall not be liable for any incidental or consequential
8 damages arising out of the use or inability to use the software.
9 **********************************************************************************************/
10 
11 #ifndef RTIREFLEX_SAFE_TYPECODE_H
12 #define RTIREFLEX_SAFE_TYPECODE_H
13 
14 #include <tuple>
15 #include <vector>
16 #include <array>
17 #include <string>
18 #include <iostream>
19 #include <boost/type_traits.hpp>
20 
21 #include <ndds/ndds_cpp.h>
22 #include "reflex/dllexport.h"
23 
24 namespace reflex {
25 
26  namespace detail {
27  REFLEX_DLL_EXPORT const char *get_readable_ex_code(DDS_ExceptionCode_t ex);
28  REFLEX_DLL_EXPORT void check_exception_code(const char * message, DDS_ExceptionCode_t ex);
29  }
30 
46  template <class T>
47  class SafeTypeCode
48  {
49  DDS_TypeCodeFactory * factory_;
50  DDS_TypeCode * typecode_;
51  bool is_shared_;
52 
53  public:
54 
59  explicit SafeTypeCode(DDS_TypeCode * tc)
60  : factory_(DDS_TypeCodeFactory::get_instance()),
61  typecode_(tc),
62  is_shared_(false)
63  { }
64 
69  explicit SafeTypeCode(const DDS_TypeCode * tc)
70  : factory_(DDS_TypeCodeFactory::get_instance()),
71  typecode_(const_cast<DDS_TypeCode *>(tc)),
72  is_shared_(true)
73  { }
74 
77  SafeTypeCode(DDS_TypeCodeFactory * fact,
78  DDS_TypeCode * tc)
79  : factory_(fact),
80  typecode_(tc),
81  is_shared_(false)
82  { }
83 
86  SafeTypeCode(DDS_TypeCodeFactory * fact,
87  const DDS_TypeCode * tc)
88  : factory_(fact),
89  typecode_(const_cast<DDS_TypeCode *>(tc)),
90  is_shared_(true)
91  { }
92 
99  SafeTypeCode(const SafeTypeCode & safetc)
100  : factory_(safetc.factory_)
101  {
102  if (safetc.is_shared_)
103  {
104  typecode_ = safetc.typecode_;
105  is_shared_ = true;
106  }
107  else
108  {
109  DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
110  typecode_ = factory_->clone_tc(safetc.typecode_, ex);
111  is_shared_ = false;
112  detail::check_exception_code(
113  "SafeTypeCode::SafeTypeCode: Unable to clone typecode, error = ",
114  ex);
115  }
116  }
117 
125  {
126  SafeTypeCode(rhs).swap(*this);
127  return *this;
128  }
129 
130 #ifdef REFLEX_HAS_RVALUE_REF
131 
137  : factory_(src.factory_),
138  typecode_(src.typecode_),
139  is_shared_(src.is_shared_)
140  {
141  src.factory_ = 0;
142  src.typecode_ = 0;
143  }
144 
150  {
151  this->swap(src);
152  return *this;
153  }
154 
155 #endif
156 
161  {
162  DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
163  if (factory_ && typecode_ && !is_shared_)
164  {
165  factory_->delete_tc(typecode_, ex);
166 
167  if (ex != DDS_NO_EXCEPTION_CODE)
168  {
169  std::cerr << "~SafeTypeCode: Unable to delete typecode, error = "
170  << detail::get_readable_ex_code(ex)
171  << std::endl;
172  // Do not throw.
173  }
174  }
175  }
176 
180  DDS_TypeCode * get()
181  {
182  return typecode_;
183  }
184 
187  const DDS_TypeCode * get() const
188  {
189  return typecode_;
190  }
191 
195  DDS_TypeCode * release()
196  {
197  is_shared_ = true;
198  return typecode_;
199  }
200 
203  void swap(SafeTypeCode & stc) throw()
204  {
205  std::swap(factory_, stc.factory_);
206  std::swap(typecode_, stc.typecode_);
207  std::swap(is_shared_, stc.is_shared_);
208  }
209  };
210 
213  template <class T>
214  void swap(SafeTypeCode<T> & lhs, SafeTypeCode<T> & rhs) throw()
215  {
216  lhs.swap(rhs);
217  }
218 
219 
220 } // namespace reflex
221 
222 
223 #endif // RTIREFLEX_SAFE_TYPECODE_H
224 
SafeTypeCode(SafeTypeCode &&src)
Moves the ownership of the TypeCode from src to a newly created SafeTypeCode object. The src typecode is set to NULL.
Definition: safe_typecode.h:136
SafeTypeCode(DDS_TypeCode *tc)
Construct an SafeTypeCode object that owns the TypeCode.
Definition: safe_typecode.h:59
SafeTypeCode & operator=(const SafeTypeCode &rhs)
Create a copy of the argument SafeTypeCode.
Definition: safe_typecode.h:124
~SafeTypeCode()
Deletes the underlying TypeCode if the object was was constructed using a non-const TypeCode...
Definition: safe_typecode.h:160
SafeTypeCode(DDS_TypeCodeFactory *fact, DDS_TypeCode *tc)
Construct an SafeTypeCode object that owns the TypeCode.
Definition: safe_typecode.h:77
SafeTypeCode(const SafeTypeCode &safetc)
Create a copy of the argument SafeTypeCode.
Definition: safe_typecode.h:99
void swap(AutoDynamicData &lhs, AutoDynamicData &rhs)
Swap the contents of two AutoDynamicData instances. Never throws.
Definition: auto_dd.cxx:106
#define REFLEX_DLL_EXPORT
Definition: dllexport.h:35
SafeTypeCode(DDS_TypeCodeFactory *fact, const DDS_TypeCode *tc)
Construct an SafeTypeCode object that does not own the TypeCode.
Definition: safe_typecode.h:86
void swap(SafeTypeCode &stc)
Swap the contents of two SafeTypeCode objects. Never throws.
Definition: safe_typecode.h:203
SafeTypeCode(const DDS_TypeCode *tc)
Construct an SafeTypeCode object that does not own the TypeCode.
Definition: safe_typecode.h:69
A type-safe, exception-safe wrapper for DDS TypeCode.
Definition: reflex_fwd.h:27
DDS_TypeCode * release()
Release the ownership of the underlying TypeCode. The SafeTypeCode object remains usable...
Definition: safe_typecode.h:195