source: rrlib_rtti_conversion/tRegisteredConversionOperation.h @ 8:b9554b04aa0f

17.03
Last change on this file since 8:b9554b04aa0f was 8:b9554b04aa0f, checked in by Max Reichardt <mreichardt@…>, 2 years ago

Adds conversion operations for tuples - and unifies 'for-each' and 'get-element' conversion operations for vectors and arrays

File size: 12.1 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/rtti_conversion/tRegisteredConversionOperation.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2016-07-15
27 *
28 * \brief   Contains tRegisteredConversionOperation
29 *
30 * \b tRegisteredConversionOperation
31 *
32 * Conversion operation registered for runtime lookup.
33 * Registered operations may be applicable to multiple combinations of data types.
34 * They can always be compiled - and may not be usable directly.
35 *
36 * They must exist until the program shuts down.
37 * If they are allocated via new, they can be flagged to be deleted at shutdown.
38 *
39 */
40//----------------------------------------------------------------------
41#ifndef __rrlib__rtti_conversion__tRegisteredConversionOperation_h__
42#define __rrlib__rtti_conversion__tRegisteredConversionOperation_h__
43
44//----------------------------------------------------------------------
45// External includes (system with <>, local with "")
46//----------------------------------------------------------------------
47#include "rrlib/rtti/rtti.h"
48#include "rrlib/rtti/tParameterDefinition.h"
49#include <atomic>
50
51//----------------------------------------------------------------------
52// Internal includes with ""
53//----------------------------------------------------------------------
54#include "rrlib/thread/tMutex.h"
55
56//----------------------------------------------------------------------
57// Namespace declaration
58//----------------------------------------------------------------------
59namespace rrlib
60{
61namespace rtti
62{
63namespace conversion
64{
65
66//----------------------------------------------------------------------
67// Forward declarations / typedefs / enums
68//----------------------------------------------------------------------
69struct tConversionOption;
70struct tConversionOptionStaticCast;
71
72/*!
73 * Used to encode supported types of tRegisteredConversionOperations for external tools
74 * This enum is to be extended if further filters are needed.
75 */
76enum class tSupportedTypeFilter : uint8_t
77{
78  SINGLE,              //!< Only a single type is supported
79  BINARY_SERIALIZABLE, //!< All binary-serializable types are supported
80  STRING_SERIALIZABLE, //!< All string-serializable types are supported
81  LISTS,               //!< All list types are supported
82  ALL,                 //!< All types are supported
83
84  // Special operations defined in rrlib_rtti_conversion (known in Java tooling)
85  STATIC_CAST,         //!< Types supported by static casts (only used for tStaticCastOperation)
86  FOR_EACH,            //!< Types supported by for-each operation
87  GET_LIST_ELEMENT,    //!< Types supported by get list element
88  ARRAY_TO_VECTOR,     //!< Types supported by array to vector operation
89  GET_TUPLE_ELEMENT    //!< Types supported by get tuple element operation
90};
91
92//----------------------------------------------------------------------
93// Class declaration
94//----------------------------------------------------------------------
95//! Registered conversion operation
96/*!
97 * Conversion operation registered for runtime lookup.
98 * Registered operations may be applicable to multiple combinations of data types.
99 * They can always be compiled - and may not be usable directly.
100 *
101 * They must exist until the program shuts down.
102 * If they are allocated via new, they can be flagged to be deleted at shutdown.
103 */
104class tRegisteredConversionOperation : public rrlib::util::tNoncopyable
105{
106
107//----------------------------------------------------------------------
108// Public methods and typedefs
109//----------------------------------------------------------------------
110public:
111
112  /*! Name of static cast operation */
113  static const char* cSTATIC_CAST_NAME;
114
115  /*! Supported types for one end of cast operation */
116  struct tSupportedTypes
117  {
118    /*! Type filter */
119    tSupportedTypeFilter filter;
120
121    /*! In case 'filter' is SINGLE, contains the single supported type; otherwise it is ignored */
122    rrlib::rtti::tType single_type;
123
124    /*! Constructor for multiple type support */
125    tSupportedTypes(tSupportedTypeFilter filter) : filter(filter), single_type() {}
126
127    /*! Custructor for single type support */
128    tSupportedTypes(const rrlib::rtti::tType& single_type) : filter(tSupportedTypeFilter::SINGLE), single_type(single_type) {}
129
130
131//    /*!
132//     * Is type supported?
133//     *
134//     * \param type Type to check
135//     * \return Whether type is supported
136//     */
137//    bool IsTypeSupported(const rrlib::rtti::tType& type)
138//    {
139//      switch (filter)
140//      {
141//      case tSupportedTypeFilter::SINGLE:
142//        return type == single_type;
143//        break;
144//      case tSupportedTypeFilter::BINARY_SERIALIZABLE:
145//        return type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE;
146//        break;
147//      case tSupportedTypeFilter::STRING_SERIALIZABLE:
148//        return type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE;
149//        break;
150//      case tSupportedTypeFilter::STATIC_CAST_SUPPORT:
151//        return // TODO? Do we actually need this method (since type support ;
152//        break;
153//      }
154//    }
155  };
156
157  /*! Data structure for managing registered operations */
158  struct tRegisteredOperations
159  {
160    /*! The list of registered operations */
161    typedef rrlib::serialization::tRegister<const tRegisteredConversionOperation*, 64, 64, uint16_t> tOperationsRegister;
162    tOperationsRegister operations;
163
164    /*! List of operations to auto-delete */
165    typedef rrlib::concurrent_containers::tRegister<std::unique_ptr<const tRegisteredConversionOperation>, 32, 32> tAutoDeleteRegister;
166    tAutoDeleteRegister auto_delete;
167
168    /*! Registered static cast operations */
169    typedef rrlib::serialization::tRegister<const tConversionOptionStaticCast*, 64, 64, uint16_t> tStaticCastRegister;
170    tStaticCastRegister static_casts;
171  };
172
173
174  virtual ~tRegisteredConversionOperation();
175
176  /*!
177   * Deserializes registered conversion operation from input stream and returns any registered operation matching the deserialized data.
178   *
179   * \param stream Stream to deserialize from
180   * \param throw_exception_if_not_found Throw std::runtime_error if no matching registered operation could be found?
181   * \return Registered operation matching the deserialized data. nullptr if no such operation exists.
182   */
183  static const tRegisteredConversionOperation* Deserialize(rrlib::serialization::tInputStream& stream, bool throw_exception_if_not_found = false);
184
185  /*!
186   * Find registered conversion operation with specified name that support specified source and destination types
187   *
188   * \param name Name of conversion operation
189   * \return Registered operation with the specified name. Second indicates whether there are more registered conversion operations with this name.
190   */
191  static std::pair<const tRegisteredConversionOperation*, bool> Find(const std::string& name);
192
193  /*!
194   * Find registered conversion operation with specified name that support specified source and destination types
195   *
196   * \param name Name of conversion operation
197   * \param source_type Source type of operation (optional)
198   * \param destination_type Destination type of operation (optional)
199   * \return Registered operation with the specified name and types.
200   * \throw Throws std::runtime_error if conversion was not found or is ambiguous.
201   */
202  static const tRegisteredConversionOperation& Find(const std::string& name, const tType& source_type, const tType& destination_type);
203
204  /*!
205   * Gets conversion option for converting the specified types.
206   * Needs to be overridden unless single_conversion_option is set.
207   *
208   * \param source_type Source Type
209   * \param destination_type Destination Type
210   * \param parameter Conversion parameter (nullptr means default)
211   * \return Conversion option for the specified types (result's type is tConversionOptionType::NONE if no option for specified types can be provided)
212   */
213  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const;
214
215  /*!
216   * \return Local handle of operation
217   */
218  uint16_t GetHandle() const
219  {
220    return handle;
221  }
222
223  /*!
224   * \return Registered type conversion operations.
225   */
226  static const tRegisteredOperations& GetRegisteredOperations()
227  {
228    return RegisteredOperations();
229  }
230
231  /*!
232   * \return Name of conversion operation
233   */
234  const char* Name() const
235  {
236    return name.Get();
237  }
238
239  /*!
240   * \return Parameter of this conversion operation (possibly empty if operation has no parameter)
241   */
242  const tParameterDefinition& Parameter() const
243  {
244    return parameter;
245  }
246
247  /*!
248   * \return Supported source types of cast operation
249   */
250  const tSupportedTypes& SupportedDestinationTypes() const
251  {
252    return supported_destination_types;
253  }
254
255  /*!
256   * \return Supported source types of cast operation
257   */
258  const tSupportedTypes& SupportedSourceTypes() const
259  {
260    return supported_source_types;
261  }
262
263//----------------------------------------------------------------------
264// Protected types
265//----------------------------------------------------------------------
266protected:
267
268  /*!
269   * \param name Name of conversion operation (must be unique for every supported combination of source and destination types)
270   * \param supported_source_types Supported source types
271   * \param supported_destination_types Supported destination types
272   * \param single_conversion_option If operation provides only a single conversion option - points to this option (otherwise override GetConversionOptions())
273   * \param parameter Any parameter of conversion operation (optional)
274   */
275  tRegisteredConversionOperation(util::tManagedConstCharPointer name, const tSupportedTypes& supported_source_types, const tSupportedTypes& supported_destination_types,
276                                 const tConversionOption* single_conversion_option = nullptr, const tParameterDefinition& parameter = tParameterDefinition());
277
278  /*!
279   * Adds this operation to list of operations that are automatically deleted on shutdown.
280   * This should only be done with operations allocated via new() and not deleted elsewhere.
281   */
282  void AutoDelete();
283
284//----------------------------------------------------------------------
285// Private fields and methods
286//----------------------------------------------------------------------
287private:
288
289  friend class tStaticCastOperation;
290
291  /*! Name of conversion operation (must be unique for every supported combination of source and destination types) */
292  util::tManagedConstCharPointer name;
293
294  /*! Supported source and destination types */
295  const tSupportedTypes supported_source_types, supported_destination_types;
296
297  /*! Parameter for this conversion operation (may be empty) */
298  const tParameterDefinition parameter;
299
300  /*! If operation provides only a single conversion option - points to this option */
301  const tConversionOption* single_conversion_option;
302
303  /*! Local handle of operation */
304  uint16_t handle;
305
306
307  /*! constructor for tStaticCastOperation */
308  tRegisteredConversionOperation();
309
310  /*!
311   * \return Registered type conversion operations.
312   */
313  static tRegisteredOperations& RegisteredOperations();
314};
315
316
317serialization::tOutputStream& operator << (serialization::tOutputStream& stream, const tRegisteredConversionOperation& operation);
318
319//----------------------------------------------------------------------
320// End of namespace declaration
321//----------------------------------------------------------------------
322}
323}
324}
325
326
327#endif
Note: See TracBrowser for help on using the repository browser.