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 namespace armarx
39 {
40  class Variant;
42 
44 
45  template <typename T>
46  inline constexpr bool always_false = false;
47 
48  /**
49  @page Variants Variants
50  @tableofcontents
51 
52  Variants provide a mechanism to store several types of data in one construct and send them via \ref ice "Ice".
53  The Variant class offers a unified interface for storing and accessing values of several data types.
54  It is one of the essential data types of ArmarX and can be used in Ice communication.
55  Variants can be extended and several Variant-based implementations of simple or complex data types
56  like 6D poses are available in ArmarX.
57  @note Complex data types in the variant context are all that are not int, float, bool, double or string.
58 
59  @section ArmarXCore-Variants-Usage Basic Variant Usage
60  Variants can store instances of all classes that implement the *VariantDataClass* Ice interface.
61  For the basic data types *int, bool, float, double* and *std::string* there are three main ways for creating a Variant.
62 
63  In the following code three int-Variant instances are created using the different ways of instantiation:
64 
65  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization1
66 
67  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization2
68 
69  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Initialization3
70 
71  This works analogously for the other basic data types.
72  The setting of complex datatypes work similarly:
73 
74  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage
75  @note The `TestComplexFloat` is from the HowTo @ref ArmarXCore-HowTos-CustomVariant "How to Create Custom Variant Types".
76 
77  The stored values can be retrieved using the respective getter methods:
78 
79  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantDocumentation Retrieval
80 
81  Or for complex types:
82 
83  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage2
84 
85  Note that after assigning a value to a variant and therefore after initially determining the Variant's type,
86  changing the type is not possible anymore. Any assignment of data of a different than the set type will result
87  in a LocalException.
88 
89  There exist several implementations of Variant-types apart from the elementary ones:
90  - TimestampVariant for timestamp values in Variants
91  - MatrixFloat for matrices in Variants
92  - ChannelRef for channel references in Variants
93  - DatafieldRef for a reference to a channel's data field
94  .
95  List of all Variants: \ref VariantsGrp "Variant Group"
96 
97  There are further classes that realize flexible containers of Variant-values, which are Variants themselves:
98  - VariantContainer, the base class for container types that store Variants
99  - StringValueMap for string-Variant mappings
100  - SingleTypeVariantList for lists of Variants
101 
102  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.
103  Since Ice interfaces always have a specific type, we need these classes with a common base class (VariantDataClass and VariantContainerBase).
104 
105  Take a look at @ref ArmarXCore-HowTos-CustomVariant "How to Create Custom Variant Types" if you want to implement your own specialized Variant classes.
106 
107  @section ArmarXCore-Variants-Serialization Serialization of Variants as JSON
108  It is easy to serialize a Variant into a JSON format. Every Variant type has this feature built in.
109  You only need the armarx::JSONObject for the serialization and deserialization:
110 
111  @snippet ArmarXCore/observers/test/VariantTest.cpp VariantJSON Usage
112 
113  The JSON then looks as follows:
114  \verbatim
115  {
116  "value" : {
117  "typeName" : "::armarx::FloatVariantData",
118  "value" : 3.0
119  }
120  }
121  \endverbatim
122 
123 
124 
125  @page ArmarXCore-HowTos-CustomVariant How to Create Custom Variant Types
126 
127  Apart from the built-in types, Variants are capable of handling instances of arbitrary types as long as they inherit from VariantDataClass.
128  To create a custom Variant type, four steps need to be taken:
129  - Write an Ice interface with the basic type description
130  - Add a Variant type id for the new type
131  - Write a C++ implementation of the type
132  - Add the created type to the object factory registry
133  .
134 
135 
136  @subsection custom_variants_interface Ice Interface
137 
138  The first part of a custom Variant type is an Ice interface that allows using the new type in Ice communication.
139  The interface should inherit from VariantDataClass and define the intended data structure.
140 
141  In this example, we implement a custom Variant type for complex numbers, defined by a real and an imaginary part, both stored as floats.
142 
143  @code
144  module armarx
145  {
146  class ComplexFloatBase extends VariantDataClass
147  {
148  float real;
149  float imag;
150  };
151  };
152  @endcode
153 
154 
155  @subsection custom_variants_type_id Type Id
156 
157 
158  Add a VariantTypeId declaration somewhere in the variant's header.
159  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Variant Type
160  @b Note: @a armarx::ComplexFloatBase must be unique in all ArmarX projects.
161 
162  @subsection custom_variants_implementation C++ Implementation
163 
164  The second part of a custom Variant data type is the C++ implementation of the defined Ice interface ComplexFloatBase.
165  There are three types of methods that need to be present in the implementation:
166  - Custom data type interface
167  - Parameterized constructors
168  - getReal, getImag for accessing the data value
169  .
170  - Standard data type interface
171  - ice_clone
172  - clone
173  - output for printing the data value
174  - getType for retrieving the Id of the new type
175  - validate for checking the data's sanity
176  .
177  - Serialization -
178  - serialize, deserialize for serializing to JSON for MemoryX
179  .
180  .
181 
182  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Class Definition
183 
184  The next step is to define a pointer type for the new data type:
185 
186  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Pointer Type Definition
187 
188 
189  @subsection custom_variants_object_factory Object Factory
190 
191  Finally, the new type needs to be registered to allow it to be used in Ice communication.
192  The factory tells ArmarX, which exact type to instantiate when the respective interface is used in communication.
193  In this case, whenever a ComplexFloatBase is transferred via Ice, it is translated into a TestComplexFloat on reception.
194 
195  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat ObjectFactory
196 
197  The variable needs to be initalized in the the cpp-file of the Object Factory like this:
198 
199  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat ObjectFactoryCPP
200 
201 
202  @subsection custom_variants_usage Usage
203 
204  The new data type can be used as if it was one of the types already included in ArmarX:
205 
206  @snippet ArmarXCore/observers/test/VariantTest.cpp TestComplexFloat Usage
207 
208  If you want to receive Variants via Ice (e.g. implement an interface that uses variants),
209  the ObjectFactory-header of the library, where the variant is implemented, needs to
210  be included and the library needs to be linked.
211 
212  \@note If you want to use the variant in the statechart editor, see @ref ArmarXGui-HowTos-Add-DataType-To-StatechartContext
213 
214  @defgroup VariantsGrp Variants
215  @ingroup ObserversGrp
216  @copydoc Variants
217  */
218  /**
219  * @class Variant
220  * @ingroup VariantsGrp
221  * @brief The Variant class is described here: @ref Variants
222  */
223  class Variant : virtual public VariantBase
224  {
225  public:
226  Variant();
227  Variant(const Variant& source);
228 
229  /**
230  * Construct a Variant from a non-VariantDataClass instance, e.g. from an int
231  *
232  * @tparam T The desired type of the Variant
233  * @param var The initialization value as a T-instance
234  * @param t For type checking only: Do not use
235  */
236  template <class T>
237  Variant(const T& var,
238  typename std::enable_if_t<!(std::is_base_of_v<VariantDataClass, T> ||
239  std::is_pointer_v<T>)>* t = nullptr)
240  {
241  invalidate();
242  set<T>(var);
243  }
244 
245  /**
246  * Construct a Variant from a string.
247  *
248  * @param var The initialization value
249  */
250  Variant(char const var[])
251  {
252  invalidate();
253  setString(var);
254  }
255 
256  /**
257  * Construct a Variant from a reference to a VariantDataClass instance. The VariantDataClass is cloned!
258  *
259  * @tparam T The desired type of the Variant
260  * @param var The initialization value as a T-instance
261  * @param t For type checking only: Do not use.
262  */
263  template <class T>
264  Variant(const T& var,
265  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
266  {
267  invalidate();
268  setClass(var);
269  }
270 
271  /**
272  * Construct a Variant from an IceHandle to a VariantDataClass instance. This is a float pointer copy.
273  *
274  * @tparam T The desired type of the Variant
275  * @param var The initialization value as a handle to a T-instance
276  * @param t For type checking only: Do not use.
277  */
278  template <class T>
280  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
281  {
282  invalidate();
283  setClass(var);
284  }
285 
286  /**
287  * Construct a Variant from a pointer to a VariantDataClass instance. The VariantDataClass is cloned!
288  *
289  * @tparam T The desired type of the Variant
290  * @param var The initialization value as a pointer to a T-instance
291  * @param t For type checking only: Do not use.
292  */
293  template <class T>
294  Variant(const T* var,
295  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>* t = nullptr)
296  {
297  invalidate();
298  setClass(*var);
299  }
300 
301  /**
302  * Checks if the Variant is initialized and the stored value is valid with respect to the Variant's type.
303  *
304  * Inherited from VariantBase Ice interface.
305  */
306  bool validate(const Ice::Current& c = Ice::emptyCurrent) const override;
307 
308  /**
309  * Returns a copy of the Variant.
310  */
311  virtual VariantPtr clone() const;
312 
313 
314  // Setters
315 
316  /**
317  * Sets the Variant's type to typeId. A Variant's type can not be changed after it has been set.
318  *
319  * @throws LocalException if a different type has already been set.
320  *
321  * Inherited from VariantBase Ice interface.
322  */
323  void setType(VariantTypeId typeId, const Ice::Current& c = Ice::emptyCurrent) override;
324 
325  /**
326  * Sets the Variant's value to n. The Variant's type is fixed to VariantType::Int.
327  *
328  * @throws InvalidTypeException if a different type has already been set.
329  *
330  * Inherited from VariantBase Ice interface.
331  */
332  void setInt(int n, const Ice::Current& c = Ice::emptyCurrent) override;
333 
334  /**
335  * Sets the Variant's value to n. The Variant's type is fixed to VariantType::Long.
336  *
337  * @throws InvalidTypeException if a different type has already been set.
338  *
339  * Inherited from VariantBase Ice interface.
340  */
341  void setLong(long n, const Ice::Current& c = Ice::emptyCurrent) override;
342 
343  /**
344  * Sets the Variant's value to f. The Variant's type is fixed to VariantType::Float.
345  *
346  * @throws InvalidTypeException if a different type has already been set.
347  *
348  * Inherited from VariantBase Ice interface.
349  */
350  void setFloat(float f, const Ice::Current& c = Ice::emptyCurrent) override;
351 
352  /**
353  * Sets the Variant's value to d. The Variant's type is fixed to VariantType::Double.
354  *
355  * @throws InvalidTypeException if a different type has already been set.
356  *
357  * Inherited from VariantBase Ice interface.
358  */
359  void setDouble(double d, const Ice::Current& c = Ice::emptyCurrent) override;
360 
361  /**
362  * Sets the Variant's value to s. The Variant's type is fixed to VariantType::String.
363  *
364  * @throws InvalidTypeException if a different type has already been set.
365  *
366  * Inherited from VariantBase Ice interface.
367  */
368  void setString(const std::string& s, const Ice::Current& c = Ice::emptyCurrent) override;
369 
370  /**
371  * Sets the Variant's value to b. The Variant's type is fixed to VariantType::Bool.
372  *
373  * @throws InvalidTypeException if a different type has already been set.
374  *
375  * Inherited from VariantBase Ice interface.
376  */
377  void setBool(bool b, const Ice::Current& c = Ice::emptyCurrent) override;
378 
379  /**
380  * Sets the Variant's value to variantDataClass. The Variant's type is fixed to the type of variantDataClass. Flat pointer copy!
381  *
382  * @throws InvalidTypeException if a different type has already been set.
383  *
384  * Inherited from VariantBase Ice interface.
385  */
386  void setClass(const VariantDataClassPtr& variantDataClass);
387 
388  /**
389  * Sets the Variant's value to variantDataClass. The Variant's type is fixed to the type of variantDataClass. The data class is cloned!
390  *
391  * @throws InvalidTypeException if a different type has already been set.
392  *
393  * Inherited from VariantBase Ice interface.
394  */
395  void setClass(const VariantDataClass& variantDataClass);
396 
397 
398  // Getters
399 
400 
401  /**
402  * Return the Variant's value as int.
403  *
404  * @throws InvalidTypeException if the Variant's type is not VariantType::Int
405  * @throws NotInitializedException if the Variant is uninitialized
406  *
407  * Inherited from VariantBase Ice interface.
408  */
409  int getInt(const Ice::Current& c = Ice::emptyCurrent) const override;
410 
411  /**
412  * Return the Variant's value as long.
413  *
414  * @throws InvalidTypeException if the Variant's type is not VariantType::Long
415  * @throws NotInitializedException if the Variant is uninitialized
416  *
417  * Inherited from VariantBase Ice interface.
418  */
419  long getLong(const Ice::Current& c = Ice::emptyCurrent) const override;
420 
421  /**
422  * Return the Variant's value as float.
423  *
424  * @throws InvalidTypeException if the Variant's type is not VariantType::Float
425  * @throws NotInitializedException if the Variant is uninitialized
426  *
427  * Inherited from VariantBase Ice interface.
428  */
429  float getFloat(const Ice::Current& c = Ice::emptyCurrent) const override;
430 
431  /**
432  * Return the Variant's value as double.
433  *
434  * @throws InvalidTypeException if the Variant's type is not VariantType::Double
435  * @throws NotInitializedException if the Variant is uninitialized
436  *
437  * Inherited from VariantBase Ice interface.
438  */
439  double getDouble(const Ice::Current& c = Ice::emptyCurrent) const override;
440 
441  /**
442  * Return the Variant's value as string.
443  *
444  * @throws InvalidTypeException if the Variant's type is not VariantType::String
445  * @throws NotInitializedException if the Variant is uninitialized
446  *
447  * Inherited from VariantBase Ice interface.
448  */
449  std::string getString(const Ice::Current& c = Ice::emptyCurrent) const override;
450 
451  /**
452  * Return the Variant's value as bool.
453  *
454  * @throws InvalidTypeException if the Variant's type is not VariantType::Bool
455  * @throws NotInitializedException if the Variant is uninitialized
456  *
457  * Inherited from VariantBase Ice interface.
458  */
459  bool getBool(const Ice::Current& c = Ice::emptyCurrent) const override;
460 
461  /**
462  * Return the Variant's value as TVariantDataClass.
463  *
464  * @tparam TVariantDataClass The type for returning the data
465  * @throws InvalidTypeException if the Variant's type is not compatible to TVariantDataClass
466  * @throws NotInitializedException if the Variant is uninitialized
467  */
468  template <class TVariantDataClass>
470  getClass() const
471  {
472  if (!getInitialized())
473  {
475  }
476 
479 
480  if (!ptr)
481  {
482  throw InvalidTypeException(
483  "Variant::getClass failed: actual type of value: " + data->ice_id() +
484  " stored type id: " + typeToString(getType()) +
485  ", desired type: " + GetType<TVariantDataClass>());
486  }
487 
488  return ptr;
489  }
490 
491  // Helper setter method using templates
492 
493  /**
494  * Template-based setter for the Variant's value for VariantDataClass-instances.
495  *
496  * @tparam T The desired type of the Variant
497  *
498  * @throws InvalidTypeException if a type other than T has already been set.
499  *
500  * @returns For type checking only: Do not use
501  */
502  template <typename T>
503  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>>
504  set(const VariantDataClassPtr& variantDataClass)
505  {
506  setClass(variantDataClass);
507  }
508 
509  /**
510  * Template-based setter for the Variant's value for non-VariantDataClass-instances.
511  * Values not derived from VariantDataClass are not allowed, thus this method always throws an exception.
512  *
513  * @tparam T The desired type of the Variant
514  *
515  * @throws InvalidTypeException
516  *
517  * @returns For type checking only: Do not use
518  */
519  template <typename T>
520  typename std::enable_if_t<!std::is_base_of_v<VariantDataClass, T>>
521  set(const T& value)
522  {
523  static_assert(std::is_base_of_v<VariantData, typename T::element_type>,
524  "Only basic types or from VariantDataClass derived classes can be "
525  "template parameters");
526  static int invType = hashTypeName(InvalidVariantData::ice_staticId());
527 
528  if (getType() == invType)
529  {
530  setType(hashTypeName(value->ice_id()));
531  }
532  else if (getType() != hashTypeName(value->ice_id()))
533  {
534  throw InvalidTypeException();
535  }
536 
537  data = T::dynamicCast(value->ice_clone());
538  }
539 
540  // Helper getter method using templates
541  /**
542  * Template-based getter for the Variant's value.
543  *
544  * @tparam T Type of the desired value, that inherits from VariantDataClass (e.g: Vector3, LinkedPose, ChannelRef).
545  *
546  * @throws NotInitializedException if the Variant has not been initialized yet
547  * @throws InvalidTypeException if T is not compatible with the Variant's internal type
548  *
549  * @returns a shared pointer to the desired data type (e.g: Vector3Ptr)
550  */
551  template <typename T>
552  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, T>, IceInternal::Handle<T>>
553  get() const
554  {
555  return getClass<T>();
556  }
557 
558  template <typename T>
559  typename std::enable_if_t<std::is_base_of_v<VariantDataClass, typename T::element_type>, T>
560  get() const
561  {
562  return getClass<typename T::element_type>();
563  }
564 
565  /**
566  * This getter is only called if a wrong template parameter is given (i.e: the type does not inherit from VariantDataClass).
567  *
568  * @throws InvalidTypeException
569  *
570  * @returns For type checking only: Do not use
571  *
572  * @note There exist specializations of this method that allow the basic types bool, int, float, double and std::string
573  */
574  template <typename T>
575  typename std::enable_if_t<(std::is_standard_layout_v<T> && std::is_trivial_v<T>) ||
576  std::is_same_v<std::string, T>,
577  T>
578  get() const
579  {
580  static_assert(always_false<T>,
581  "This function must not be called directly, it is only for primitive "
582  "types which have specializations");
583  }
584 
585  // Properties
586 
587  /**
588  * Return the Variant's internal type.
589  *
590  * @return The Variant's type as a VariantTypeId
591  */
592  VariantTypeId getType(const Ice::Current& c = Ice::emptyCurrent) const override;
593 
594  /**
595  * Return the Variant's internal type.
596  *
597  * @return The Variant's type as a string
598  */
599  std::string getTypeName(const Ice::Current& c = Ice::emptyCurrent) const override;
600 
601  /**
602  * Tells if the Variant is properly initialized.
603  */
604  bool getInitialized(const Ice::Current& c = Ice::emptyCurrent) const override;
605 
606  // Operators
607 
608  Variant&
609  operator=(int n)
610  {
611  setInt(n);
612  return *this;
613  }
614 
615  Variant&
616  operator=(long n)
617  {
618  setLong(n);
619  return *this;
620  }
621 
622  Variant&
623  operator=(float f)
624  {
625  setFloat(f);
626  return *this;
627  }
628 
629  Variant&
630  operator=(double d)
631  {
632  setDouble(d);
633  return *this;
634  }
635 
636  Variant&
637  operator=(const std::string& s)
638  {
639  setString(s);
640  return *this;
641  }
642 
643  Variant&
644  operator=(bool b)
645  {
646  setBool(b);
647  return *this;
648  }
649 
650  Variant& operator=(const VariantDataClass& prototype);
651  Variant& operator=(const VariantDataClassPtr& prototype);
652  Variant& operator=(const Variant& prototype);
653 
654  // Streaming operator
655 
656  friend std::ostream&
657  operator<<(std::ostream& stream, const Variant& rhs)
658  {
659  rhs.output(stream);
660  return stream;
661  }
662 
663  friend std::ostream&
664  operator<<(std::ostream& stream, const VariantPtr& rhs)
665  {
666  if (rhs)
667  {
668  rhs->output(stream);
669  }
670  else
671  {
672  stream << "Null VariantPtr";
673  }
674 
675  return stream;
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 // *******************************************************
910 // Types for basic variants
911 // *******************************************************
912 namespace armarx::VariantType
913 {
914  // These const variables are abbreviations to the function that provides the type id of Variants
915  const VariantTypeId Invalid = Variant::addTypeName("::armarx::InvalidVariantData");
916  const VariantTypeId Bool = Variant::addTypeName("::armarx::BoolVariantData");
917  const VariantTypeId Int = Variant::addTypeName("::armarx::IntVariantData");
918  const VariantTypeId Long = Variant::addTypeName("::armarx::LongVariantData");
919  const VariantTypeId Float = Variant::addTypeName("::armarx::FloatVariantData");
920  const VariantTypeId Double = Variant::addTypeName("::armarx::DoubleVariantData");
921  const VariantTypeId String = Variant::addTypeName("::armarx::StringVariantData");
922  bool IsBasicType(VariantTypeId id);
923 } // namespace armarx::VariantType
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::Variant::setClass
void setClass(const VariantDataClassPtr &variantDataClass)
Sets the Variant's value to variantDataClass.
Definition: Variant.cpp:466
armarx::Variant::getInitialized
bool getInitialized(const Ice::Current &c=Ice::emptyCurrent) const override
Tells if the Variant is properly initialized.
Definition: Variant.cpp:698
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::Variant::operator=
Variant & operator=(float f)
Definition: Variant.h:623
armarx::Variant::setLong
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:372
armarx::Variant::getDouble
double getDouble(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as double.
Definition: Variant.cpp:551
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:708
armarx::Variant::operator<<
friend std::ostream & operator<<(std::ostream &stream, const Variant &rhs)
Definition: Variant.h:657
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:679
armarx::Variant::operator=
Variant & operator=(double d)
Definition: Variant.h:630
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:578
armarx::Variant::clone
virtual VariantPtr clone() const
Returns a copy of the Variant.
Definition: Variant.cpp:333
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:428
armarx::Variant::operator=
Variant & operator=(long n)
Definition: Variant.h:616
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::Variant::getTypes
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition: Variant.cpp:863
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:916
armarx::Variant::Variant
Variant()
Definition: Variant.cpp:317
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:553
armarx::Variant::getTypeName
std::string getTypeName(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's internal type.
Definition: Variant.cpp:685
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:279
armarx::Variant::getLong
long getLong(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as long.
Definition: Variant.cpp:513
armarx::Variant::setInt
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:355
IceInternal::Handle< Variant >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:920
armarx::Variant::setDouble
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition: Variant.cpp:409
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::Variant::setBool
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition: Variant.cpp:447
armarx::Variant::getString
std::string getString(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as string.
Definition: Variant.cpp:570
armarx::VariantType::Invalid
const VariantTypeId Invalid
Definition: Variant.h:915
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:495
armarx::Variant::setFloat
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition: Variant.cpp:390
armarx::Variant::operator=
Variant & operator=(int n)
Definition: Variant.h:609
armarx::Variant::Variant
Variant(char const var[])
Construct a Variant from a string.
Definition: Variant.h:250
armarx::Variant::operator=
Variant & operator=(bool b)
Definition: Variant.h:644
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:504
armarx::Variant::get
std::enable_if_t< std::is_base_of_v< VariantDataClass, typename T::element_type >, T > get() const
Definition: Variant.h:560
armarx::Variant::typeToString
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition: Variant.cpp:848
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
armarx::VariantType
Definition: ChannelRef.h:167
armarx::Variant::getFloat
float getFloat(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as float.
Definition: Variant.cpp:532
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:237
armarx::Variant::getOutputValueOnly
virtual std::string getOutputValueOnly() const
Returns the formatted content of the Variant as a string.
Definition: Variant.cpp:608
armarx::always_false
constexpr bool always_false
Definition: Variant.h:46
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:43
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
armarx::VariantType::IsBasicType
bool IsBasicType(VariantTypeId id)
Definition: Variant.cpp:893
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:264
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:521
armarx::Variant::setType
void setType(VariantTypeId typeId, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's type to typeId.
Definition: Variant.cpp:343
armarx::operator<<
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
Definition: PythonApplicationManager.cpp:285
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:917
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:813
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:294
armarx::Variant::output
void output(std::ostream &stream) const
Outputs a formatted representation of the Variant to stream.
Definition: Variant.cpp:782
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:921
armarx::Variant::getClass
IceInternal::Handle< TVariantDataClass > getClass() const
Return the Variant's value as TVariantDataClass.
Definition: Variant.h:470
armarx::Variant::getBool
bool getBool(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as bool.
Definition: Variant.cpp:589
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:27
armarx::Variant::addTypeName
static VariantTypeId addTypeName(const std::string &typeName)
Register a new type for the use in a Variant.
Definition: Variant.cpp:869