Variant.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore::core
19 * @author Kai Welke (welke@kit.edu)
20 * @date 2011
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #pragma once
26 
27 #include <map>
28 #include <string>
29 #include <type_traits>
30 
31 #include <IceUtil/Handle.h>
32 
33 #include <ArmarXCore/interface/observers/VariantBase.h>
34 #include <ArmarXCore/interface/observers/VariantContainers.h>
37 
38 
39 namespace armarx
40 {
41  class Variant;
43 
45 
46  template <typename T>
47  inline constexpr bool always_false = false;
48 
49  /**
50  @page Variants Variants
51  @tableofcontents
52 
53  Variants provide a mechanism to store several types of data in one construct and send them via \ref ice "Ice".
54  The Variant class offers a unified interface for storing and accessing values of several data types.
55  It is one of the essential data types of ArmarX and can be used in Ice communication.
56  Variants can be extended and several Variant-based implementations of simple or complex data types
57  like 6D poses are available in ArmarX.
58  @note Complex data types in the variant context are all that are not int, float, bool, double or string.
59 
60  @section ArmarXCore-Variants-Usage Basic Variant Usage
61  Variants can store instances of all classes that implement the *VariantDataClass* Ice interface.
62  For the basic data types *int, bool, float, double* and *std::string* there are three main ways for creating a Variant.
63 
64  In the following code three int-Variant instances are created using the different ways of instantiation:
65 
66  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization1
67 
68  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization2
69 
70  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization3
71 
72  This works analogously for the other basic data types.
73  The setting of complex datatypes work similarly:
74 
75  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage
76  @note The `TestComplexFloat` is from the HowTo @ref ArmarXCore-HowTos-CustomVariant "How to Create Custom Variant Types".
77 
78  The stored values can be retrieved using the respective getter methods:
79 
80  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Retrieval
81 
82  Or for complex types:
83 
84  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage2
85 
86  Note that after assigning a value to a variant and therefore after initially determining the Variant's type,
87  changing the type is not possible anymore. Any assignment of data of a different than the set type will result
88  in a LocalException.
89 
90  There exist several implementations of Variant-types apart from the elementary ones:
91  - TimestampVariant for timestamp values in Variants
92  - MatrixFloat for matrices in Variants
93  - ChannelRef for channel references in Variants
94  - DatafieldRef for a reference to a channel's data field
95  .
96  List of all Variants: \ref VariantsGrp "Variant Group"
97 
98  There are further classes that realize flexible containers of Variant-values, which are Variants themselves:
99  - VariantContainer, the base class for container types that store Variants
100  - StringValueMap for string-Variant mappings
101  - SingleTypeVariantList for lists of Variants
102 
103  These containers are needed for the same reason as the Variant themselves: We need to be able to send different data via the same Ice interface.
104  Since Ice interfaces always have a specific type, we need these classes with a common base class (VariantDataClass and VariantContainerBase).
105 
106  Take a look at @ref ArmarXCore-HowTos-CustomVariant "How to Create Custom Variant Types" if you want to implement your own specialized Variant classes.
107 
108  @section ArmarXCore-Variants-Serialization Serialization of Variants as JSON
109  It is easy to serialize a Variant into a JSON format. Every Variant type has this feature built in.
110  You only need the armarx::JSONObject for the serialization and deserialization:
111 
112  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantJSON Usage
113 
114  The JSON then looks as follows:
115  \verbatim
116  {
117  "value" : {
118  "typeName" : "::armarx::FloatVariantData",
119  "value" : 3.0
120  }
121  }
122  \endverbatim
123 
124 
125 
126  @page ArmarXCore-HowTos-CustomVariant How to Create Custom Variant Types
127 
128  Apart from the built-in types, Variants are capable of handling instances of arbitrary types as long as they inherit from VariantDataClass.
129  To create a custom Variant type, four steps need to be taken:
130  - Write an Ice interface with the basic type description
131  - Add a Variant type id for the new type
132  - Write a C++ implementation of the type
133  - Add the created type to the object factory registry
134  .
135 
136 
137  @subsection custom_variants_interface Ice Interface
138 
139  The first part of a custom Variant type is an Ice interface that allows using the new type in Ice communication.
140  The interface should inherit from VariantDataClass and define the intended data structure.
141 
142  In this example, we implement a custom Variant type for complex numbers, defined by a real and an imaginary part, both stored as floats.
143 
144  @code
145  module armarx
146  {
147  class ComplexFloatBase extends VariantDataClass
148  {
149  float real;
150  float imag;
151  };
152  };
153  @endcode
154 
155 
156  @subsection custom_variants_type_id Type Id
157 
158 
159  Add a VariantTypeId declaration somewhere in the variant's header.
160  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Variant Type
161  @b Note: @a armarx::ComplexFloatBase must be unique in all ArmarX projects.
162 
163  @subsection custom_variants_implementation C++ Implementation
164 
165  The second part of a custom Variant data type is the C++ implementation of the defined Ice interface ComplexFloatBase.
166  There are three types of methods that need to be present in the implementation:
167  - Custom data type interface
168  - Parameterized constructors
169  - getReal, getImag for accessing the data value
170  .
171  - Standard data type interface
172  - ice_clone
173  - clone
174  - output for printing the data value
175  - getType for retrieving the Id of the new type
176  - validate for checking the data's sanity
177  .
178  - Serialization -
179  - serialize, deserialize for serializing to JSON for MemoryX
180  .
181  .
182 
183  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Class Definition
184 
185  The next step is to define a pointer type for the new data type:
186 
187  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Pointer Type Definition
188 
189 
190  @subsection custom_variants_object_factory Object Factory
191 
192  Finally, the new type needs to be registered to allow it to be used in Ice communication.
193  The factory tells ArmarX, which exact type to instantiate when the respective interface is used in communication.
194  In this case, whenever a ComplexFloatBase is transferred via Ice, it is translated into a TestComplexFloat on reception.
195 
196  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat ObjectFactory
197 
198  The variable needs to be initalized in the the cpp-file of the Object Factory like this:
199 
200  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat ObjectFactoryCPP
201 
202 
203  @subsection custom_variants_usage Usage
204 
205  The new data type can be used as if it was one of the types already included in ArmarX:
206 
207  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage
208 
209  If you want to receive Variants via Ice (e.g. implement an interface that uses variants),
210  the ObjectFactory-header of the library, where the variant is implemented, needs to
211  be included and the library needs to be linked.
212 
213  \@note If you want to use the variant in the statechart editor, see @ref ArmarXGui-HowTos-Add-DataType-To-StatechartContext
214 
215  @defgroup VariantsGrp Variants
216  @ingroup ObserversGrp
217  @copydoc Variants
218  */
219  /**
220  * @class Variant
221  * @ingroup VariantsGrp
222  * @brief The Variant class is described here: @ref Variants
223  */
224  class Variant : virtual public VariantBase
225  {
226  public:
227  Variant();
228  Variant(const Variant& source);
229 
230  /**
231  * Construct a Variant from a non-VariantDataClass instance, e.g. from an int
232  *
233  * @tparam T The desired type of the Variant
234  * @param var The initialization value as a T-instance
235  * @param t For type checking only: Do not use
236  */
237  template <class T>
238  Variant(const T& var,
239  typename std::enable_if_t<!(std::is_base_of_v<VariantDataClass, T> ||
240  std::is_pointer_v<T>)>* t = nullptr)
241  {
242  invalidate();
243  set<T>(var);
244  }
245 
246  /**
247  * Construct a Variant from a string.
248  *
249  * @param var The initialization value
250  */
251  Variant(char const var[])
252  {
253  invalidate();
254  setString(var);
255  }
256 
257  /**
258  * Construct a Variant from a reference to a VariantDataClass instance. The VariantDataClass is cloned!
259  *
260  * @tparam T The desired type of the Variant
261  * @param var The initialization value as a T-instance
262  * @param t For type checking only: Do not use.
263  */
264  template <class T>
265  Variant(const T& var,
266  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
267  {
268  invalidate();
269  setClass(var);
270  }
271 
272  /**
273  * Construct a Variant from an IceHandle to a VariantDataClass instance. This is a float pointer copy.
274  *
275  * @tparam T The desired type of the Variant
276  * @param var The initialization value as a handle to a T-instance
277  * @param t For type checking only: Do not use.
278  */
279  template <class T>
281  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
282  {
283  invalidate();
284  setClass(var);
285  }
286 
287  /**
288  * Construct a Variant from a pointer to a VariantDataClass instance. The VariantDataClass is cloned!
289  *
290  * @tparam T The desired type of the Variant
291  * @param var The initialization value as a pointer to a T-instance
292  * @param t For type checking only: Do not use.
293  */
294  template <class T>
295  Variant(const T* var,
296  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
297  {
298  invalidate();
299  setClass(*var);
300  }
301 
302 
303  /**
304  * Checks if the Variant is initialized and the stored value is valid with respect to the Variant's type.
305  *
306  * Inherited from VariantBase Ice interface.
307  */
308  bool validate(const Ice::Current& c = Ice::emptyCurrent) const override;
309 
310  /**
311  * Returns a copy of the Variant.
312  */
313  virtual VariantPtr clone() const;
314 
315 
316  // Setters
317 
318  /**
319  * Sets the Variant's type to typeId. A Variant's type can not be changed after it has been set.
320  *
321  * @throws LocalException if a different type has already been set.
322  *
323  * Inherited from VariantBase Ice interface.
324  */
325  void setType(VariantTypeId typeId, const Ice::Current& c = Ice::emptyCurrent) override;
326 
327  /**
328  * Sets the Variant's value to n. The Variant's type is fixed to VariantType::Int.
329  *
330  * @throws InvalidTypeException if a different type has already been set.
331  *
332  * Inherited from VariantBase Ice interface.
333  */
334  void setInt(int n, const Ice::Current& c = Ice::emptyCurrent) override;
335 
336  /**
337  * Sets the Variant's value to n. The Variant's type is fixed to VariantType::Long.
338  *
339  * @throws InvalidTypeException if a different type has already been set.
340  *
341  * Inherited from VariantBase Ice interface.
342  */
343  void setLong(long n, const Ice::Current& c = Ice::emptyCurrent) override;
344 
345  /**
346  * Sets the Variant's value to f. The Variant's type is fixed to VariantType::Float.
347  *
348  * @throws InvalidTypeException if a different type has already been set.
349  *
350  * Inherited from VariantBase Ice interface.
351  */
352  void setFloat(float f, const Ice::Current& c = Ice::emptyCurrent) override;
353 
354  /**
355  * Sets the Variant's value to d. The Variant's type is fixed to VariantType::Double.
356  *
357  * @throws InvalidTypeException if a different type has already been set.
358  *
359  * Inherited from VariantBase Ice interface.
360  */
361  void setDouble(double d, const Ice::Current& c = Ice::emptyCurrent) override;
362 
363  /**
364  * Sets the Variant's value to s. The Variant's type is fixed to VariantType::String.
365  *
366  * @throws InvalidTypeException if a different type has already been set.
367  *
368  * Inherited from VariantBase Ice interface.
369  */
370  void setString(const std::string& s, const Ice::Current& c = Ice::emptyCurrent) override;
371 
372  /**
373  * Sets the Variant's value to b. The Variant's type is fixed to VariantType::Bool.
374  *
375  * @throws InvalidTypeException if a different type has already been set.
376  *
377  * Inherited from VariantBase Ice interface.
378  */
379  void setBool(bool b, const Ice::Current& c = Ice::emptyCurrent) override;
380 
381  /**
382  * Sets the Variant's value to variantDataClass. The Variant's type is fixed to the type of variantDataClass. Flat pointer copy!
383  *
384  * @throws InvalidTypeException if a different type has already been set.
385  *
386  * Inherited from VariantBase Ice interface.
387  */
388  void setClass(const VariantDataClassPtr& variantDataClass);
389 
390  /**
391  * Sets the Variant's value to variantDataClass. The Variant's type is fixed to the type of variantDataClass. The data class is cloned!
392  *
393  * @throws InvalidTypeException if a different type has already been set.
394  *
395  * Inherited from VariantBase Ice interface.
396  */
397  void setClass(const VariantDataClass& variantDataClass);
398 
399 
400  // Getters
401 
402 
403  /**
404  * Return the Variant's value as int.
405  *
406  * @throws InvalidTypeException if the Variant's type is not VariantType::Int
407  * @throws NotInitializedException if the Variant is uninitialized
408  *
409  * Inherited from VariantBase Ice interface.
410  */
411  int getInt(const Ice::Current& c = Ice::emptyCurrent) const override;
412 
413  /**
414  * Return the Variant's value as long.
415  *
416  * @throws InvalidTypeException if the Variant's type is not VariantType::Long
417  * @throws NotInitializedException if the Variant is uninitialized
418  *
419  * Inherited from VariantBase Ice interface.
420  */
421  long getLong(const Ice::Current& c = Ice::emptyCurrent) const override;
422 
423  /**
424  * Return the Variant's value as float.
425  *
426  * @throws InvalidTypeException if the Variant's type is not VariantType::Float
427  * @throws NotInitializedException if the Variant is uninitialized
428  *
429  * Inherited from VariantBase Ice interface.
430  */
431  float getFloat(const Ice::Current& c = Ice::emptyCurrent) const override;
432 
433  /**
434  * Return the Variant's value as double.
435  *
436  * @throws InvalidTypeException if the Variant's type is not VariantType::Double
437  * @throws NotInitializedException if the Variant is uninitialized
438  *
439  * Inherited from VariantBase Ice interface.
440  */
441  double getDouble(const Ice::Current& c = Ice::emptyCurrent) const override;
442 
443  /**
444  * Return the Variant's value as string.
445  *
446  * @throws InvalidTypeException if the Variant's type is not VariantType::String
447  * @throws NotInitializedException if the Variant is uninitialized
448  *
449  * Inherited from VariantBase Ice interface.
450  */
451  std::string getString(const Ice::Current& c = Ice::emptyCurrent) const override;
452 
453  /**
454  * Return the Variant's value as bool.
455  *
456  * @throws InvalidTypeException if the Variant's type is not VariantType::Bool
457  * @throws NotInitializedException if the Variant is uninitialized
458  *
459  * Inherited from VariantBase Ice interface.
460  */
461  bool getBool(const Ice::Current& c = Ice::emptyCurrent) const override;
462 
463  /**
464  * Return the Variant's value as TVariantDataClass.
465  *
466  * @tparam TVariantDataClass The type for returning the data
467  * @throws InvalidTypeException if the Variant's type is not compatible to TVariantDataClass
468  * @throws NotInitializedException if the Variant is uninitialized
469  */
470  template <class TVariantDataClass>
472  getClass() const
473  {
474  if (!getInitialized())
475  {
477  }
478 
481 
482  if (!ptr)
483  {
484  throw InvalidTypeException(
485  "Variant::getClass failed: actual type of value: " + data->ice_id() +
486  " stored type id: " + typeToString(getType()) +
487  ", desired type: " + GetType<TVariantDataClass>());
488  }
489 
490  return ptr;
491  }
492 
493 
494  // Helper setter method using templates
495 
496  /**
497  * Template-based setter for the Variant's value for VariantDataClass-instances.
498  *
499  * @tparam T The desired type of the Variant
500  *
501  * @throws InvalidTypeException if a type other than T has already been set.
502  *
503  * @returns For type checking only: Do not use
504  */
505  template <typename T>
506  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>
507  set(const VariantDataClassPtr& variantDataClass)
508  {
509  setClass(variantDataClass);
510  }
511 
512  /**
513  * Template-based setter for the Variant's value for non-VariantDataClass-instances.
514  * Values not derived from VariantDataClass are not allowed, thus this method always throws an exception.
515  *
516  * @tparam T The desired type of the Variant
517  *
518  * @throws InvalidTypeException
519  *
520  * @returns For type checking only: Do not use
521  */
522  template <typename T>
523  typename std::enable_if_t<!std::is_base_of_v<VariantDataClass, T>>
524  set(const T& value)
525  {
526  static_assert(std::is_base_of_v<VariantData, typename T::element_type>,
527  "Only basic types or from VariantDataClass derived classes can be "
528  "template parameters");
529  static int invType = hashTypeName(InvalidVariantData::ice_staticId());
530 
531  if (getType() == invType)
532  {
533  setType(hashTypeName(value->ice_id()));
534  }
535  else if (getType() != hashTypeName(value->ice_id()))
536  {
537  throw InvalidTypeException();
538  }
539 
540  data = T::dynamicCast(value->ice_clone());
541  }
542 
543  // Helper getter method using templates
544  /**
545  * Template-based getter for the Variant's value.
546  *
547  * @tparam T Type of the desired value, that inherits from VariantDataClass (e.g: Vector3, LinkedPose, ChannelRef).
548  *
549  * @throws NotInitializedException if the Variant has not been initialized yet
550  * @throws InvalidTypeException if T is not compatible with the Variant's internal type
551  *
552  * @returns a shared pointer to the desired data type (e.g: Vector3Ptr)
553  */
554  template <typename T>
555  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>, IceInternal::Handle<T>>
556  get() const
557  {
558  return getClass<T>();
559  }
560 
561  template <typename T>
562  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, typename T::element_type>, T>
563  get() const
564  {
565  return getClass<typename T::element_type>();
566  }
567 
568  /**
569  * This getter is only called if a wrong template parameter is given (i.e: the type does not inherit from VariantDataClass).
570  *
571  * @throws InvalidTypeException
572  *
573  * @returns For type checking only: Do not use
574  *
575  * @note There exist specializations of this method that allow the basic types bool, int, float, double and std::string
576  */
577  template <typename T>
578  typename std::enable_if_t<(std::is_standard_layout_v<T> && std::is_trivial_v<T>) ||
579  std::is_same_v<std::string, T>,
580  T>
581  get() const
582  {
583  static_assert(always_false<T>,
584  "This function must not be called directly, it is only for primitive "
585  "types which have specializations");
586  }
587 
588  // Properties
589 
590  /**
591  * Return the Variant's internal type.
592  *
593  * @return The Variant's type as a VariantTypeId
594  */
595  VariantTypeId getType(const Ice::Current& c = Ice::emptyCurrent) const override;
596 
597  /**
598  * Return the Variant's internal type.
599  *
600  * @return The Variant's type as a string
601  */
602  std::string getTypeName(const Ice::Current& c = Ice::emptyCurrent) const override;
603 
604  /**
605  * Tells if the Variant is properly initialized.
606  */
607  bool getInitialized(const Ice::Current& c = Ice::emptyCurrent) const override;
608 
609 
610  // Operators
611 
612  Variant&
613  operator=(int n)
614  {
615  setInt(n);
616  return *this;
617  }
618  Variant&
619  operator=(long n)
620  {
621  setLong(n);
622  return *this;
623  }
624  Variant&
625  operator=(float f)
626  {
627  setFloat(f);
628  return *this;
629  }
630  Variant&
631  operator=(double d)
632  {
633  setDouble(d);
634  return *this;
635  }
636  Variant&
637  operator=(const std::string& s)
638  {
639  setString(s);
640  return *this;
641  }
642  Variant&
643  operator=(bool b)
644  {
645  setBool(b);
646  return *this;
647  }
648  Variant& operator=(const VariantDataClass& prototype);
649  Variant& operator=(const VariantDataClassPtr& prototype);
650  Variant& operator=(const Variant& prototype);
651 
652 
653  // Streaming operator
654 
655  friend std::ostream&
656  operator<<(std::ostream& stream, const Variant& rhs)
657  {
658  rhs.output(stream);
659  return stream;
660  }
661 
662  friend std::ostream&
663  operator<<(std::ostream& stream, const VariantPtr& rhs)
664  {
665  if (rhs)
666  {
667  rhs->output(stream);
668  }
669  else
670  {
671  stream << "Null VariantPtr";
672  }
673 
674  return stream;
675  }
676 
677 
678  // Static tools
679 
680  /**
681  * Return the name of the registered type typeId.
682  *
683  * @throws UnknownTypeException if typeId is not registered yet.
684  */
685  static std::string typeToString(VariantTypeId typeId);
686 
687  /**
688  * Returns the mapping of currently registered types.
689  */
690  static const std::map<VariantTypeId, std::string>& getTypes();
691 
692  /**
693  * Register a new type for the use in a Variant.
694  *
695  * @throws LocalException if an already registered type has the same hash value as typeName.
696  */
697  static VariantTypeId addTypeName(const std::string& typeName);
698 
699  /**
700  * Template-based getter for a type name
701  */
702  template <typename Type>
703  static std::string
705  {
706  std::string typeName = GetTypeString<Type>();
707 
708  if (typeName.size() > 1)
709  {
710  typeName = typeName.substr(0, typeName.size() - 1);
711  }
712 
713  return typeName;
714  }
715 
716  /**
717  * Returns the formatted content of the Variant as a string.
718  */
719  virtual std::string getOutputValueOnly() const;
720 
721  protected:
722  /**
723  * Outputs a formatted representation of the Variant to stream.
724  */
725  void output(std::ostream& stream) const;
726  mutable bool initialized;
727 
728 
729  private:
730  /**
731  * Invalidates the Variant.
732  */
733  void invalidate();
734 
735  public:
736  /**
737  * Compute and return a hash value for a given type name.
738  */
739  static int hashTypeName(const std::string& typeName);
740 
741  private:
742  /**
743  * Create and return the internal mapping of registered types.
744  */
745  static std::map<VariantTypeId, std::string>& types();
746  };
747 
748  using StringVariantMap = std::map<std::string, Variant>;
749 
750  // *******************************************************
751  // Integral
752  // *******************************************************
753 
754  template <>
755  Variant::Variant(const std::int8_t& var, void* t);
756  template <>
757  std::int8_t Variant::get<std::int8_t>() const;
758  template <>
759  void Variant::set<std::int8_t>(const std::int8_t& value);
760 
761  template <>
762  Variant::Variant(const std::int16_t& var, void* t);
763  template <>
764  std::int16_t Variant::get<std::int16_t>() const;
765  template <>
766  void Variant::set<std::int16_t>(const std::int16_t& value);
767 
768  template <>
769  Variant::Variant(const std::int32_t& var, void* t);
770  template <>
771  std::int32_t Variant::get<std::int32_t>() const;
772  template <>
773  void Variant::set<std::int32_t>(const std::int32_t& value);
774 
775  template <>
776  Variant::Variant(const std::int64_t& var, void* t);
777  template <>
778  std::int64_t Variant::get<std::int64_t>() const;
779  template <>
780  void Variant::set<std::int64_t>(const std::int64_t& value);
781 
782  template <>
783  Variant::Variant(const std::uint8_t& var, void* t);
784  template <>
785  std::uint8_t Variant::get<std::uint8_t>() const;
786  template <>
787  void Variant::set<std::uint8_t>(const std::uint8_t& value);
788 
789  template <>
790  Variant::Variant(const std::uint8_t& var, void* t);
791  template <>
792  std::uint8_t Variant::get<std::uint8_t>() const;
793  template <>
794  void Variant::set<std::uint8_t>(const std::uint8_t& value);
795 
796  template <>
797  Variant::Variant(const std::uint16_t& var, void* t);
798  template <>
799  std::uint16_t Variant::get<std::uint16_t>() const;
800  template <>
801  void Variant::set<std::uint16_t>(const std::uint16_t& value);
802 
803  template <>
804  Variant::Variant(const std::uint32_t& var, void* t);
805  template <>
806  std::uint32_t Variant::get<std::uint32_t>() const;
807  template <>
808  void Variant::set<std::uint32_t>(const std::uint32_t& value);
809 
810  template <>
811  Variant::Variant(const std::uint64_t& var, void* t);
812  template <>
813  std::uint64_t Variant::get<std::uint64_t>() const;
814  template <>
815  void Variant::set<std::uint64_t>(const std::uint64_t& value);
816 
817  // *******************************************************
818  // Constructors
819  // *******************************************************
820  template <>
821  Variant::Variant(const float& var, void* t);
822  template <>
823  Variant::Variant(const double& var, void* t);
824  template <>
825  Variant::Variant(const bool& var, void* t);
826  template <>
827  Variant::Variant(const std::string& var, void* t);
828 
829  // *******************************************************
830  // Template specialization for getter and setter
831  // *******************************************************
832  template <>
833  bool Variant::get<bool>() const;
834  template <>
835  float Variant::get<float>() const;
836  template <>
837  double Variant::get<double>() const;
838  template <>
839  std::string Variant::get<std::string>() const;
840 
841  template <>
842  void Variant::set<bool>(const bool& value);
843  template <>
844  void Variant::set<float>(const float& value);
845  template <>
846  void Variant::set<double>(const double& value);
847  template <>
848  void Variant::set<std::string>(const std::string& value);
849 
850  // *******************************************************
851  // Explicit Instantiation Declaration
852  // *******************************************************
853 
854  extern template Variant::Variant(const std::int8_t& var, void* t);
855  extern template std::int8_t Variant::get<std::int8_t>() const;
856  extern template void Variant::set<std::int8_t>(const std::int8_t& value);
857 
858  extern template Variant::Variant(const std::int16_t& var, void* t);
859  extern template std::int16_t Variant::get<std::int16_t>() const;
860  extern template void Variant::set<std::int16_t>(const std::int16_t& value);
861 
862  extern template Variant::Variant(const std::int32_t& var, void* t);
863  extern template std::int32_t Variant::get<std::int32_t>() const;
864  extern template void Variant::set<std::int32_t>(const std::int32_t& value);
865 
866  extern template Variant::Variant(const std::int64_t& var, void* t);
867  extern template std::int64_t Variant::get<std::int64_t>() const;
868  extern template void Variant::set<std::int64_t>(const std::int64_t& value);
869 
870  extern template Variant::Variant(const std::uint8_t& var, void* t);
871  extern template std::uint8_t Variant::get<std::uint8_t>() const;
872  extern template void Variant::set<std::uint8_t>(const std::uint8_t& value);
873 
874  extern template Variant::Variant(const std::uint8_t& var, void* t);
875  extern template std::uint8_t Variant::get<std::uint8_t>() const;
876  extern template void Variant::set<std::uint8_t>(const std::uint8_t& value);
877 
878  extern template Variant::Variant(const std::uint16_t& var, void* t);
879  extern template std::uint16_t Variant::get<std::uint16_t>() const;
880  extern template void Variant::set<std::uint16_t>(const std::uint16_t& value);
881 
882  extern template Variant::Variant(const std::uint32_t& var, void* t);
883  extern template std::uint32_t Variant::get<std::uint32_t>() const;
884  extern template void Variant::set<std::uint32_t>(const std::uint32_t& value);
885 
886  extern template Variant::Variant(const std::uint64_t& var, void* t);
887  extern template std::uint64_t Variant::get<std::uint64_t>() const;
888  extern template void Variant::set<std::uint64_t>(const std::uint64_t& value);
889 
890  extern template Variant::Variant(const float& var, void* t);
891  extern template float Variant::get<float>() const;
892  extern template void Variant::set<float>(const float& value);
893 
894  extern template Variant::Variant(const double& var, void* t);
895  extern template double Variant::get<double>() const;
896  extern template void Variant::set<double>(const double& value);
897 
898  extern template Variant::Variant(const bool& var, void* t);
899  extern template bool Variant::get<bool>() const;
900  extern template void Variant::set<bool>(const bool& value);
901 
902  extern template Variant::Variant(const std::string& var, void* t);
903  extern template std::string Variant::get<std::string>() const;
904  extern template void Variant::set<std::string>(const std::string& value);
905 
906  std::ostream& operator<<(std::ostream& stream, const VariantDataClass& variant);
907 } // namespace armarx
908 // *******************************************************
909 // Types for basic variants
910 // *******************************************************
911 namespace armarx::VariantType
912 {
913  // These const variables are abbreviations to the function that provides the type id of Variants
914  const VariantTypeId Invalid = Variant::addTypeName("::armarx::InvalidVariantData");
915  const VariantTypeId Bool = Variant::addTypeName("::armarx::BoolVariantData");
916  const VariantTypeId Int = Variant::addTypeName("::armarx::IntVariantData");
917  const VariantTypeId Long = Variant::addTypeName("::armarx::LongVariantData");
918  const VariantTypeId Float = Variant::addTypeName("::armarx::FloatVariantData");
919  const VariantTypeId Double = Variant::addTypeName("::armarx::DoubleVariantData");
920  const VariantTypeId String = Variant::addTypeName("::armarx::StringVariantData");
921  bool IsBasicType(VariantTypeId id);
922 } // namespace armarx::VariantType
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::Variant::setClass
void setClass(const VariantDataClassPtr &variantDataClass)
Sets the Variant's value to variantDataClass.
Definition: Variant.cpp:374
armarx::Variant::getInitialized
bool getInitialized(const Ice::Current &c=Ice::emptyCurrent) const override
Tells if the Variant is properly initialized.
Definition: Variant.cpp:591
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::Variant::operator=
Variant & operator=(float f)
Definition: Variant.h:625
armarx::Variant::setLong
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:290
armarx::Variant::getDouble
double getDouble(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as double.
Definition: Variant.cpp:452
armarx::Variant::validate
bool validate(const Ice::Current &c=Ice::emptyCurrent) const override
Checks if the Variant is initialized and the stored value is valid with respect to the Variant's type...
Definition: Variant.cpp:601
armarx::Variant::operator<<
friend std::ostream & operator<<(std::ostream &stream, const Variant &rhs)
Definition: Variant.h:656
armarx::StringVariantMap
std::map< std::string, Variant > StringVariantMap
Definition: Variant.h:748
GetTypeString.h
armarx::Variant::getType
VariantTypeId getType(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's internal type.
Definition: Variant.cpp:574
armarx::Variant::operator=
Variant & operator=(double d)
Definition: Variant.h:631
armarx::Variant::get
std::enable_if_t<(std::is_standard_layout_v< T > &&std::is_trivial_v< T >)||std::is_same_v< std::string, T >, T > get() const
This getter is only called if a wrong template parameter is given (i.e: the type does not inherit fro...
Definition: Variant.h:581
armarx::Variant::clone
virtual VariantPtr clone() const
Returns a copy of the Variant.
Definition: Variant.cpp:255
armarx::Variant::setString
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition: Variant.cpp:340
armarx::Variant::operator=
Variant & operator=(long n)
Definition: Variant.h:619
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::Variant::getTypes
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition: Variant.cpp:746
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
armarx::Variant::Variant
Variant()
Definition: Variant.cpp:235
armarx::Variant::get
std::enable_if_t< std::is_base_of_v< VariantDataClass, T >, IceInternal::Handle< T > > get() const
Template-based getter for the Variant's value.
Definition: Variant.h:556
armarx::Variant::getTypeName
std::string getTypeName(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's internal type.
Definition: Variant.cpp:579
armarx::Variant::Variant
Variant(const IceInternal::Handle< T > &var, typename std::enable_if_t< std::is_base_of_v< VariantDataClass, T >> *t=nullptr)
Construct a Variant from an IceHandle to a VariantDataClass instance.
Definition: Variant.h:280
armarx::Variant::getLong
long getLong(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as long.
Definition: Variant.cpp:417
armarx::Variant::setInt
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:274
IceInternal::Handle< Variant >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::Variant::setDouble
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition: Variant.cpp:323
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::Variant::setBool
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition: Variant.cpp:357
armarx::Variant::getString
std::string getString(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as string.
Definition: Variant.cpp:470
armarx::VariantType::Invalid
const VariantTypeId Invalid
Definition: Variant.h:914
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::Variant::getInt
int getInt(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as int.
Definition: Variant.cpp:400
armarx::Variant::setFloat
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition: Variant.cpp:306
armarx::Variant::operator=
Variant & operator=(int n)
Definition: Variant.h:613
armarx::Variant::Variant
Variant(char const var[])
Construct a Variant from a string.
Definition: Variant.h:251
armarx::Variant::operator=
Variant & operator=(bool b)
Definition: Variant.h:643
armarx::Variant::set
std::enable_if_t< std::is_base_of_v< VariantDataClass, T > > set(const VariantDataClassPtr &variantDataClass)
Template-based setter for the Variant's value for VariantDataClass-instances.
Definition: Variant.h:507
armarx::Variant::get
std::enable_if_t< std::is_base_of_v< VariantDataClass, typename T::element_type >, T > get() const
Definition: Variant.h:563
armarx::Variant::typeToString
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition: Variant.cpp:732
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::VariantType
Definition: ChannelRef.h:160
armarx::Variant::getFloat
float getFloat(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as float.
Definition: Variant.cpp:434
armarx::Variant::Variant
Variant(const T &var, typename std::enable_if_t<!(std::is_base_of_v< VariantDataClass, T >||std::is_pointer_v< T >)> *t=nullptr)
Construct a Variant from a non-VariantDataClass instance, e.g.
Definition: Variant.h:238
armarx::Variant::getOutputValueOnly
virtual std::string getOutputValueOnly() const
Returns the formatted content of the Variant as a string.
Definition: Variant.cpp:504
armarx::always_false
constexpr bool always_false
Definition: Variant.h:47
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:44
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:681
armarx::VariantType::IsBasicType
bool IsBasicType(VariantTypeId id)
Definition: Variant.cpp:772
NotInitializedException.h
armarx::exceptions::user::NotInitializedException
Definition: NotInitializedException.h:34
armarx::Variant::initialized
bool initialized
Definition: Variant.h:726
armarx::Variant::operator=
Variant & operator=(const std::string &s)
Definition: Variant.h:637
armarx::Variant::Variant
Variant(const T &var, typename std::enable_if_t< std::is_base_of_v< VariantDataClass, T >> *t=nullptr)
Construct a Variant from a reference to a VariantDataClass instance.
Definition: Variant.h:265
armarx::Variant::set
std::enable_if_t<!std::is_base_of_v< VariantDataClass, T > > set(const T &value)
Template-based setter for the Variant's value for non-VariantDataClass-instances.
Definition: Variant.h:524
armarx::Variant::setType
void setType(VariantTypeId typeId, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's type to typeId.
Definition: Variant.cpp:264
armarx::operator<<
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
Definition: PythonApplicationManager.cpp:221
armarx::Variant::GetType
static std::string GetType()
Template-based getter for a type name.
Definition: Variant.h:704
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:699
armarx::Variant::Variant
Variant(const T *var, typename std::enable_if_t< std::is_base_of_v< VariantDataClass, T >> *t=nullptr)
Construct a Variant from a pointer to a VariantDataClass instance.
Definition: Variant.h:295
armarx::Variant::output
void output(std::ostream &stream) const
Outputs a formatted representation of the Variant to stream.
Definition: Variant.cpp:669
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:920
armarx::Variant::getClass
IceInternal::Handle< TVariantDataClass > getClass() const
Return the Variant's value as TVariantDataClass.
Definition: Variant.h:472
armarx::Variant::getBool
bool getBool(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as bool.
Definition: Variant.cpp:487
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::Variant::addTypeName
static VariantTypeId addTypeName(const std::string &typeName)
Register a new type for the use in a Variant.
Definition: Variant.cpp:751