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
38namespace armarx
39{
40 class Variant;
42
43 using VariantTypeId = Ice::Int;
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 {
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&
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// *******************************************************
912namespace 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
constexpr T c
The Variant class is described here: Variants.
Definition Variant.h:224
bool getInitialized(const Ice::Current &c=Ice::emptyCurrent) const override
Tells if the Variant is properly initialized.
Definition Variant.cpp:698
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
VariantTypeId getType(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's internal type.
Definition Variant.cpp:679
static std::string GetType()
Template-based getter for a type name.
Definition Variant.h:704
Variant & operator=(float f)
Definition Variant.h:623
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition Variant.cpp:863
void setClass(const VariantDataClassPtr &variantDataClass)
Sets the Variant's value to variantDataClass.
Definition Variant.cpp:466
Variant & operator=(int n)
Definition Variant.h:609
IceInternal::Handle< TVariantDataClass > getClass() const
Return the Variant's value as TVariantDataClass.
Definition Variant.h:470
Variant & operator=(const std::string &s)
Definition Variant.h:637
virtual std::string getOutputValueOnly() const
Returns the formatted content of the Variant as a string.
Definition Variant.cpp:608
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition Variant.cpp:372
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition Variant.cpp:390
std::string getString(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as string.
Definition Variant.cpp:570
friend std::ostream & operator<<(std::ostream &stream, const Variant &rhs)
Definition Variant.h:657
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition Variant.cpp:355
virtual VariantPtr clone() const
Returns a copy of the Variant.
Definition Variant.cpp:333
Variant(char const var[])
Construct a Variant from a string.
Definition Variant.h:250
Variant & operator=(long n)
Definition Variant.h:616
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
std::enable_if_t< std::is_base_of_v< VariantDataClass, typename T::element_type >, T > get() const
Definition Variant.h:560
int getInt(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as int.
Definition Variant.cpp:495
static VariantTypeId addTypeName(const std::string &typeName)
Register a new type for the use in a Variant.
Definition Variant.cpp:869
bool getBool(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as bool.
Definition Variant.cpp:589
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition Variant.cpp:428
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
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
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition Variant.cpp:447
std::string getTypeName(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's internal type.
Definition Variant.cpp:685
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
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition Variant.cpp:813
Variant & operator=(bool b)
Definition Variant.h:644
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
long getLong(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as long.
Definition Variant.cpp:513
Variant & operator=(double d)
Definition Variant.h:630
double getDouble(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as double.
Definition Variant.cpp:551
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition Variant.cpp:848
void output(std::ostream &stream) const
Outputs a formatted representation of the Variant to stream.
Definition Variant.cpp:782
void setType(VariantTypeId typeId, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's type to typeId.
Definition Variant.cpp:343
float getFloat(const Ice::Current &c=Ice::emptyCurrent) const override
Return the Variant's value as float.
Definition Variant.cpp:532
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
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
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
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition Variant.cpp:409
const VariantTypeId String
Definition Variant.h:921
const VariantTypeId Invalid
Definition Variant.h:915
const VariantTypeId Int
Definition Variant.h:917
const VariantTypeId Long
Definition Variant.h:918
const VariantTypeId Bool
Definition Variant.h:916
bool IsBasicType(VariantTypeId id)
Definition Variant.cpp:893
const VariantTypeId Double
Definition Variant.h:920
const VariantTypeId Float
Definition Variant.h:919
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
IceInternal::Handle< Variant > VariantPtr
Definition Variant.h:41
constexpr bool always_false
Definition Variant.h:46
Ice::Int VariantTypeId
Definition Variant.h:43
std::map< std::string, Variant > StringVariantMap
Definition Variant.h:748