/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _HDR_gsiTypes #define _HDR_gsiTypes #include "tlInternational.h" #include "tlException.h" #include "gsiCommon.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace tl { class Variant; } namespace gsi { // --------------------------------------------------------------------------------- // Type system of GSI class SerialArgs; class VectorAdaptor; class MapAdaptor; class StringAdaptor; class VariantAdaptor; class ClassBase; struct NoAdaptorTag; template class Class; template struct ClassTag; template class IterAdaptor; template class IterPtrAdaptor; template class ConstIterPtrAdaptor; template class FreeIterAdaptor; template const ClassBase *cls_decl (); /** * @brief Determine the size for one item in the serialization buffer */ template unsigned int item_size () { return (sizeof (X) + (sizeof (void *) - 1)) & ~(sizeof (void *) - 1); } template struct type_tag { // .. intentionally left blank .. }; /** * @brief Basic GSI type constants */ enum BasicType { T_void = 0, T_bool = 1, T_char = 2, T_schar = 3, T_uchar = 4, T_short = 5, T_ushort = 6, T_int = 7, T_uint = 8, T_long = 9, T_ulong = 10, T_longlong = 11, T_ulonglong = 12, #if defined(HAVE_64BIT_COORD) T_int128 = 100, #endif T_double = 13, T_float = 14, T_var = 15, T_string = 16, T_void_ptr = 19, T_object = 20, T_vector = 21, T_map = 22 }; /** * @brief Type tags * * "pod" are the POD types (bool, char, short, int, long, long long, double, float, unsigned variants) * "npod" types are strings, vectors, maps and variants and all other objects * - strings use StringAdaptor implementations * - vectors use VectorAdaptor implementations * - maps use MapAdaptor implementations * - variants use VariantAdaptor implementations * * The basic tags are: * - pod_direct_tag: (POD) serialized as (POD) * - pod_cref_tag: (const POD &) serialized as (POD) * - pod_ref_tag: (POD &) serialized as (POD *) with pointer != 0 * - pod_cptr_tag: (const POD *) serialized as (true, POD) or (false) * - pod_ptr_tag: (POD *) serialized as (POD *) * - npod_direct_tag: (NPOD) serialized as (NPOD *) * ownership is transferred: writer stores a new object * reader will take ownership of it. * - npod_cref_tag: (const NPOD &) serialized as (NPOD *) * (Reason for the latter decision: deserializing is that * way possible without having to call the destructor after * the value has been used) * For the adaptor classes, the ownership will be transferred. * No transfer of ownership for other classes. * - npod_ref_tag: (NPOD &) serialized as (NPOD *) with pointer != 0 * For the adaptor classes, the ownership will be transferred. * No transfer of ownership for other classes. * - npod_cptr_tag: (const NPOD *) serialized as (NPOD *) * (Reason for the latter decision: deserializing is that * way possible without having to call the destructor after * the value has been used) * For the adaptor classes, the ownership will be transferred. * No transfer of ownership for other classes. * - npod_ptr_tag: (NPOD *) serialized as (NPOD *) * For the adaptor classes, the ownership will be transferred. * No transfer of ownership for other classes. * * Enums are treated as NPOD. The reason is that technically they are among "any other type". * Enums are just a special case of "adapted types" for which client-side wrapper classes are * registered. */ struct type_tag_base { typedef tl::false_tag is_pod; typedef tl::false_tag is_npod; typedef tl::false_tag is_ref; typedef tl::false_tag is_cref; typedef tl::false_tag is_ptr; typedef tl::false_tag is_cptr; }; struct adaptor_category_tag { }; struct vector_adaptor_tag : public adaptor_category_tag { }; struct map_adaptor_tag : public adaptor_category_tag { }; struct string_adaptor_tag : public adaptor_category_tag { }; struct variant_adaptor_tag : public adaptor_category_tag { }; struct basic_type_tag : public type_tag_base { }; struct void_tag : public type_tag_base { }; struct vptr_tag : public type_tag_base { }; struct direct_tag : public basic_type_tag { }; struct pod_direct_tag : public direct_tag { typedef tl::true_tag is_pod; }; struct npod_direct_tag : public direct_tag { typedef tl::true_tag is_npod; }; struct cref_tag : public basic_type_tag { typedef tl::true_tag is_cref; }; struct pod_cref_tag : public cref_tag { typedef tl::true_tag is_pod; }; struct npod_cref_tag : public cref_tag { typedef tl::true_tag is_npod; }; struct ref_tag : public basic_type_tag { typedef tl::true_tag is_ref; }; struct pod_ref_tag : public ref_tag { typedef tl::true_tag is_pod; }; struct npod_ref_tag : public ref_tag { typedef tl::true_tag is_npod; }; struct cptr_tag : public basic_type_tag { typedef tl::true_tag is_cptr; }; struct pod_cptr_tag : public cptr_tag { typedef tl::true_tag is_pod; }; struct npod_cptr_tag : public cptr_tag { typedef tl::true_tag is_npod; }; struct ptr_tag : public basic_type_tag { typedef tl::true_tag is_ptr; }; struct pod_ptr_tag : public ptr_tag { typedef tl::true_tag is_pod; }; struct npod_ptr_tag : public ptr_tag { typedef tl::true_tag is_npod; }; struct bool_tag : public pod_direct_tag { }; struct char_tag : public pod_direct_tag { }; struct uchar_tag : public pod_direct_tag { }; struct schar_tag : public pod_direct_tag { }; struct short_tag : public pod_direct_tag { }; struct ushort_tag : public pod_direct_tag { }; struct int_tag : public pod_direct_tag { }; struct uint_tag : public pod_direct_tag { }; struct long_tag : public pod_direct_tag { }; struct ulong_tag : public pod_direct_tag { }; struct longlong_tag : public pod_direct_tag { }; struct ulonglong_tag : public pod_direct_tag { }; #if defined(HAVE_64BIT_COORD) struct int128_tag : public pod_direct_tag { }; #endif struct double_tag : public pod_direct_tag { }; struct float_tag : public pod_direct_tag { }; struct adaptor_direct_tag : public npod_direct_tag { }; struct adaptor_cref_tag : public npod_cref_tag { }; struct adaptor_ref_tag : public npod_ref_tag { }; struct adaptor_cptr_tag : public npod_cptr_tag { }; struct adaptor_ptr_tag : public npod_ptr_tag { }; struct vector_tag : public adaptor_direct_tag, public vector_adaptor_tag { }; struct map_tag : public adaptor_direct_tag, public map_adaptor_tag { }; struct string_tag : public adaptor_direct_tag, public string_adaptor_tag { }; struct var_tag : public adaptor_direct_tag, public variant_adaptor_tag { }; struct bool_cref_tag : public pod_cref_tag { }; struct char_cref_tag : public pod_cref_tag { }; struct uchar_cref_tag : public pod_cref_tag { }; struct schar_cref_tag : public pod_cref_tag { }; struct short_cref_tag : public pod_cref_tag { }; struct ushort_cref_tag : public pod_cref_tag { }; struct int_cref_tag : public pod_cref_tag { }; struct uint_cref_tag : public pod_cref_tag { }; struct long_cref_tag : public pod_cref_tag { }; struct ulong_cref_tag : public pod_cref_tag { }; struct longlong_cref_tag : public pod_cref_tag { }; struct ulonglong_cref_tag : public pod_cref_tag { }; #if defined(HAVE_64BIT_COORD) struct int128_cref_tag : public pod_cref_tag { }; #endif struct double_cref_tag : public pod_cref_tag { }; struct float_cref_tag : public pod_cref_tag { }; struct vector_cref_tag : public adaptor_cref_tag, public vector_adaptor_tag { }; struct map_cref_tag : public adaptor_cref_tag, public map_adaptor_tag { }; struct string_cref_tag : public adaptor_cref_tag, public string_adaptor_tag { }; struct var_cref_tag : public adaptor_cref_tag, public variant_adaptor_tag { }; struct bool_ref_tag : public pod_ref_tag { }; struct char_ref_tag : public pod_ref_tag { }; struct uchar_ref_tag : public pod_ref_tag { }; struct schar_ref_tag : public pod_ref_tag { }; struct short_ref_tag : public pod_ref_tag { }; struct ushort_ref_tag : public pod_ref_tag { }; struct int_ref_tag : public pod_ref_tag { }; struct uint_ref_tag : public pod_ref_tag { }; struct long_ref_tag : public pod_ref_tag { }; struct ulong_ref_tag : public pod_ref_tag { }; struct longlong_ref_tag : public pod_ref_tag { }; struct ulonglong_ref_tag : public pod_ref_tag { }; #if defined(HAVE_64BIT_COORD) struct int128_ref_tag : public pod_ref_tag { }; #endif struct double_ref_tag : public pod_ref_tag { }; struct float_ref_tag : public pod_ref_tag { }; struct vector_ref_tag : public adaptor_ref_tag, public vector_adaptor_tag { }; struct map_ref_tag : public adaptor_ref_tag, public map_adaptor_tag { }; struct string_ref_tag : public adaptor_ref_tag, public string_adaptor_tag { }; struct var_ref_tag : public adaptor_ref_tag, public variant_adaptor_tag { }; struct bool_cptr_tag : public pod_cptr_tag { }; struct char_cptr_tag : public pod_cptr_tag { }; struct uchar_cptr_tag : public pod_cptr_tag { }; struct schar_cptr_tag : public pod_cptr_tag { }; struct short_cptr_tag : public pod_cptr_tag { }; struct ushort_cptr_tag : public pod_cptr_tag { }; struct int_cptr_tag : public pod_cptr_tag { }; struct uint_cptr_tag : public pod_cptr_tag { }; struct long_cptr_tag : public pod_cptr_tag { }; struct ulong_cptr_tag : public pod_cptr_tag { }; struct longlong_cptr_tag : public pod_cptr_tag { }; struct ulonglong_cptr_tag : public pod_cptr_tag { }; #if defined(HAVE_64BIT_COORD) struct int128_cptr_tag : public pod_cptr_tag { }; #endif struct double_cptr_tag : public pod_cptr_tag { }; struct float_cptr_tag : public pod_cptr_tag { }; struct vector_cptr_tag : public adaptor_cptr_tag, public vector_adaptor_tag { }; struct map_cptr_tag : public adaptor_cptr_tag, public map_adaptor_tag { }; struct string_cptr_tag : public adaptor_cptr_tag, public string_adaptor_tag { }; struct var_cptr_tag : public adaptor_cptr_tag, public variant_adaptor_tag { }; struct bool_ptr_tag : public pod_ptr_tag { }; struct char_ptr_tag : public pod_ptr_tag { }; struct uchar_ptr_tag : public pod_ptr_tag { }; struct schar_ptr_tag : public pod_ptr_tag { }; struct short_ptr_tag : public pod_ptr_tag { }; struct ushort_ptr_tag : public pod_ptr_tag { }; struct int_ptr_tag : public pod_ptr_tag { }; struct uint_ptr_tag : public pod_ptr_tag { }; struct long_ptr_tag : public pod_ptr_tag { }; struct ulong_ptr_tag : public pod_ptr_tag { }; struct longlong_ptr_tag : public pod_ptr_tag { }; struct ulonglong_ptr_tag : public pod_ptr_tag { }; #if defined(HAVE_64BIT_COORD) struct int128_ptr_tag : public pod_ptr_tag { }; #endif struct double_ptr_tag : public pod_ptr_tag { }; struct float_ptr_tag : public pod_ptr_tag { }; struct vector_ptr_tag : public adaptor_ptr_tag, public vector_adaptor_tag { }; struct map_ptr_tag : public adaptor_ptr_tag, public map_adaptor_tag { }; struct string_ptr_tag : public adaptor_ptr_tag, public string_adaptor_tag { }; struct var_ptr_tag : public adaptor_ptr_tag, public variant_adaptor_tag { }; // all other objects struct x_tag : public npod_direct_tag { }; struct x_cref_tag : public npod_cref_tag { }; struct x_cptr_tag : public npod_cptr_tag { }; struct x_cptr_cref_tag : public x_cptr_tag { }; struct x_cptr_ref_tag : public x_cptr_tag { }; struct x_ref_tag : public npod_ref_tag { }; struct x_ptr_tag : public npod_ptr_tag { }; struct x_ptr_cref_tag : public x_ptr_tag { }; struct x_ptr_ref_tag : public x_ptr_tag { }; /** * @brief Type traits that map a C++ type to a certain tag */ template struct type_traits; template <> struct type_traits { typedef void_tag tag; typedef void value_type; typedef void inner_type; typedef void inner_k_type; static bool is_pod () { return false; } static bool is_npod () { return false; } static bool is_cref () { return false; } static bool is_ref () { return false; } static bool is_cptr () { return false; } static bool is_ptr () { return false; } static BasicType code () { return T_void; } static const ClassBase *cls_decl () { return 0; } static bool is_iter () { return false; } static size_t serial_size () { return 0; } }; // see serialization notes above template inline size_t compute_size (const void_tag &) { return 0; } template inline size_t compute_size (const basic_type_tag &) { return item_size (); } template inline size_t compute_size (const pod_direct_tag &) { return item_size (); } template inline size_t compute_size (const pod_cref_tag &) { return item_size (); } template inline size_t compute_size (const pod_ref_tag &) { return item_size (); } template inline size_t compute_size (const pod_cptr_tag &) { return item_size () + item_size (); } template inline size_t compute_size (const pod_ptr_tag &) { return item_size (); } template inline size_t compute_size (const vptr_tag &) { return item_size (); } template inline size_t compute_size (const npod_direct_tag &) { return item_size (); } template inline size_t compute_size (const npod_cref_tag &) { return item_size (); } template inline size_t compute_size (const npod_ref_tag &) { return item_size (); } template inline size_t compute_size (const npod_cptr_tag &) { return item_size (); } template inline size_t compute_size (const npod_ptr_tag &) { return item_size (); } // Note: derived, "real" traits must not overwrite tag or value_type since these // are used by the predicates and serial_size attribute. template struct generic_type_traits { typedef T tag; typedef V value_type; typedef void inner_type; typedef void inner_k_type; static bool is_pod () { return tl::value_of (typename T::is_pod ()); } static bool is_npod () { return tl::value_of (typename T::is_npod ()); } static bool is_cref () { return tl::value_of (typename T::is_cref ()); } static bool is_ref () { return tl::value_of (typename T::is_ref ()); } static bool is_cptr () { return tl::value_of (typename T::is_cptr ()); } static bool is_ptr () { return tl::value_of (typename T::is_ptr ()); } static size_t serial_size () { return compute_size (T ()); } static BasicType code () { return TC; } static const ClassBase *cls_decl () { return 0; } static bool is_iter () { return false; } }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; #if defined(HAVE_64BIT_COORD) template <> struct type_traits<__int128> : generic_type_traits { }; #endif template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; #if defined(HAVE_64BIT_COORD) template <> struct type_traits : generic_type_traits { }; #endif template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; #if defined(HAVE_64BIT_COORD) template <> struct type_traits<__int128 &> : generic_type_traits { }; #endif template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; // that is bound to a string, not a single char // template <> struct type_traits // template <> struct type_traits // template <> struct type_traits template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; #if defined(HAVE_64BIT_COORD) template <> struct type_traits : generic_type_traits { }; #endif template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; // that is not bound to avoid interpretation problems between string and char * // template <> struct type_traits : generic_type_traits { }; // template <> struct type_traits : generic_type_traits { }; // template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; #if defined(HAVE_64BIT_COORD) template <> struct type_traits<__int128 *> : generic_type_traits { }; #endif template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template <> struct type_traits : generic_type_traits { }; template struct type_traits : generic_type_traits::tag, typename type_traits::value_type, T_void> { static BasicType code () { return type_traits::code (); } static const ClassBase *cls_decl () { return type_traits::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template struct type_traits : generic_type_traits { static const ClassBase *cls_decl () { return gsi::cls_decl (); } }; template <> struct type_traits : generic_type_traits { typedef QString inner_type; }; template <> struct type_traits : generic_type_traits { typedef QString inner_type; }; template <> struct type_traits : generic_type_traits { typedef QString inner_type; }; template <> struct type_traits : generic_type_traits { typedef QString inner_type; }; template <> struct type_traits : generic_type_traits { typedef QString inner_type; }; template struct type_traits< QList > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QList & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QList & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QList * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QList * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QSet > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QSet & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QSet & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QSet * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QSet * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QVector > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QVector & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QVector & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const QVector * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QVector * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::set > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::set & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::set & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::set * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::vector > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::vector & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::vector & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::vector * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::vector * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::list > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::list & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::list & > : generic_type_traits { typedef X inner_type; }; template struct type_traits< const std::list * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< std::list * > : generic_type_traits { typedef X inner_type; }; template struct type_traits< QHash > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const QHash & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< QHash & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const QHash * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< QHash * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< QMap > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const QMap & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< QMap & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const QMap * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< QMap * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< std::map > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const std::map & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< std::map & > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< const std::map * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< std::map * > : generic_type_traits { typedef X inner_k_type; typedef Y inner_type; }; template struct type_traits< IterAdaptor > : generic_type_traits::tag, IterAdaptor, T_void> { static BasicType code () { return type_traits::code (); } static const ClassBase *cls_decl () { return type_traits::cls_decl (); } static bool is_iter () { return true; } }; template struct type_traits< IterPtrAdaptor > : generic_type_traits::tag, IterPtrAdaptor, T_void> { static BasicType code () { return type_traits::code (); } static const ClassBase *cls_decl () { return type_traits::cls_decl (); } static bool is_iter () { return true; } }; template struct type_traits< ConstIterPtrAdaptor > : generic_type_traits::tag, ConstIterPtrAdaptor, T_void> { static BasicType code () { return type_traits::code (); } static const ClassBase *cls_decl () { return type_traits::cls_decl (); } static bool is_iter () { return true; } }; template struct type_traits< FreeIterAdaptor > : generic_type_traits::tag, FreeIterAdaptor, T_void> { static BasicType code () { return type_traits::code (); } static const ClassBase *cls_decl () { return type_traits::cls_decl (); } static bool is_iter () { return true; } }; template class ArgSpec; /** * @brief A generic argument specification class * * This class provides an optional argument name and initialization. * The base class provides the interface, specializations the actual code */ class GSI_PUBLIC ArgSpecBase { public: ArgSpecBase () : m_name (), m_has_default (false) { } ArgSpecBase (const std::string &name) : m_name (name), m_has_default (false) { } ArgSpecBase (const std::string &name, bool has_default, const std::string &init_doc = std::string ()) : m_name (name), m_init_doc (init_doc), m_has_default (has_default) { } virtual ~ArgSpecBase () { } const std::string &name () const { return m_name; } const std::string &init_doc () const { return m_init_doc; } bool has_default () const { return m_has_default; } virtual tl::Variant default_value () const { return tl::Variant (); } virtual ArgSpecBase *clone () const { return new ArgSpecBase (*this); } private: std::string m_name, m_init_doc; bool m_has_default; }; /** * @brief A specialization for void */ template <> class ArgSpec : public ArgSpecBase { public: typedef void init_type; ArgSpec () : ArgSpecBase (std::string (), false) { } ArgSpec (const ArgSpec &other) : ArgSpecBase (other) { } template ArgSpec (const ArgSpec &other) : ArgSpecBase (other) { } ArgSpec (const std::string &name) : ArgSpecBase (name, false) { } virtual ArgSpecBase *clone () const { return new ArgSpec (*this); } void init () const { // TODO: throw exception tl_assert (false); } tl::Variant default_value () const { return tl::Variant (); } }; /** * @brief An implementation helper that provides a switch between classes having and having no copy ctor */ template class ArgSpecImpl : public ArgSpecBase { public: typedef const T &init_type; ArgSpecImpl () : ArgSpecBase (std::string (), false) { } ArgSpecImpl (const ArgSpec &other) : ArgSpecBase (other) { } template ArgSpecImpl (const ArgSpec &other) : ArgSpecBase (other) { } ArgSpecImpl (const std::string &name) : ArgSpecBase (name, false) { } virtual ArgSpecBase *clone () const { return new ArgSpecImpl (*this); } const T &init () const { // should never happen tl_assert (false); } tl::Variant default_value () const { return tl::Variant (); } }; /** * @brief A specialization for classes with default and copy ctor */ template class ArgSpecImpl : public ArgSpecBase { public: typedef const T &init_type; ArgSpecImpl () : ArgSpecBase (std::string (), false), mp_init (0) { } ArgSpecImpl (const ArgSpec &other) : ArgSpecBase (other), mp_init (0) { } template ArgSpecImpl (const ArgSpec &other) : ArgSpecBase (other), mp_init (0) { if (other.has_init ()) { mp_init = new T (other.init ()); } } ArgSpecImpl (const ArgSpecImpl &other) : ArgSpecBase (other), mp_init (0) { if (other.has_init ()) { mp_init = new T (other.init ()); } } ArgSpecImpl &operator= (const ArgSpecImpl &other) { if (this != &other) { ArgSpecBase::operator= (other); if (mp_init) { delete mp_init; mp_init = 0; } if (other.has_init ()) { mp_init = new T (other.init ()); } } return *this; } ArgSpecImpl (const std::string &name) : ArgSpecBase (name, false), mp_init (0) { } ArgSpecImpl (const std::string &name, const T &init) : ArgSpecBase (name, true), mp_init (new T (init)) { } ArgSpecImpl (const std::string &name, const T &init, const std::string &init_doc) : ArgSpecBase (name, true, init_doc), mp_init (new T (init)) { } ~ArgSpecImpl () { if (mp_init) { delete mp_init; mp_init = 0; } } virtual ArgSpecBase *clone () const { return new ArgSpecImpl (*this); } bool has_init () const { return mp_init != 0; } const T &init () const { tl_assert (mp_init != 0); return *mp_init; } tl::Variant default_value () const { if (mp_init) { return tl::Variant (*mp_init); } else { return tl::Variant (); } } private: T *mp_init; }; /** * @brief The generic implementation */ template class ArgSpec : public ArgSpecImpl::has_copy_constructor> { public: typedef typename tl::type_traits::has_copy_constructor cc_type; ArgSpec () : ArgSpecImpl () { } ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } template ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } ArgSpec (const std::string &name) : ArgSpecImpl (name) { } ArgSpec (const std::string &name, const T &init, const std::string &init_doc = std::string ()) : ArgSpecImpl (name, init, init_doc) { } virtual ArgSpecBase *clone () const { return new ArgSpec (*this); } }; /** * @brief The generic implementation for const references */ template class ArgSpec : public ArgSpecImpl::has_copy_constructor> { public: typedef typename tl::type_traits::has_copy_constructor cc_type; ArgSpec () : ArgSpecImpl () { } ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } template ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } ArgSpec (const std::string &name) : ArgSpecImpl (name) { } ArgSpec (const std::string &name, const T &init, const std::string &init_doc = std::string ()) : ArgSpecImpl (name, init, init_doc) { } virtual ArgSpecBase *clone () const { return new ArgSpec (*this); } }; /** * @brief The generic implementation for references */ template class ArgSpec : public ArgSpecImpl::has_copy_constructor> { public: typedef T &init_type; typedef typename tl::type_traits::has_copy_constructor cc_type; ArgSpec () : ArgSpecImpl () { } ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } template ArgSpec (const ArgSpec &other) : ArgSpecImpl (other) { } ArgSpec (const std::string &name) : ArgSpecImpl (name) { } ArgSpec (const std::string &name, const T &init, const std::string &init_doc = std::string ()) : ArgSpecImpl (name, init, init_doc) { } T &init () const { // this simplifies the implementation, but it's not really clean since the caller may modify the default. return const_cast (ArgSpecImpl::init ()); } virtual ArgSpecBase *clone () const { return new ArgSpec (*this); } }; /** * @brief Generic argument type declaration * * The type declaration carries the basic type code and flags, if the argument * is an iterator delivering the given types of a vector of the given types and * adds class informations if the type is "T_object", "T_object_ref", "T_object_cref". */ class GSI_PUBLIC ArgType { public: /** * @brief Default constructor * * Creates a void type */ ArgType (); /** * @brief Copy ctor */ ArgType (const ArgType &other); /** * @brief Destructor */ ~ArgType (); /** * @brief Assignment */ ArgType &operator= (const ArgType &other); /** * @brief Initializes with an external specification * * This method will initialize the type object referring to an external * spec object. The spec object will specify name and default * value for arguments */ template void init (const ArgSpecBase &spec) { init (); mp_spec = &spec; m_owns_spec = false; } /** * @brief Initializes with a specification * * This method will initialize the type object with a specification. * The ownership over the specification object will be transferred to * the type object. */ template void init (ArgSpecBase *spec) { init (); mp_spec = spec; m_owns_spec = true; } /** * @brief Initialize the type from a given type X * If "pass_obj" is true, the receiver of an object will always * take over the ownership over the passed object. This applies * to the case of object pointers mainly. */ template void init (bool pass_obj = false) { release_spec (); m_type = type_traits::code (); m_is_iter = type_traits::is_iter (); mp_cls = type_traits::cls_decl (); m_pass_obj = pass_obj; m_is_ref = type_traits::is_ref (); m_is_ptr = type_traits::is_ptr (); m_is_cref = type_traits::is_cref (); m_is_cptr = type_traits::is_cptr (); m_size = type_traits::serial_size (); if (mp_inner) { delete mp_inner; mp_inner = 0; } if (mp_inner_k) { delete mp_inner_k; mp_inner_k = 0; } if (type_traits::inner_type>::code () != T_void) { mp_inner = new ArgType; mp_inner->init::inner_type> (); } if (type_traits::inner_k_type>::code () != T_void) { mp_inner_k = new ArgType; mp_inner_k->init::inner_k_type> (); } } /** * @brief Checks whether the type and the given type are equivalent */ void check_type (const ArgType &a) const; /** * @brief Equality of the types * * The equality operator does not check the specification objects. */ bool operator== (const ArgType &b) const; /** * @brief Inequality */ bool operator!= (const ArgType &b) const { return !operator== (b); } /** * @brief Conversion to a string * * This method will produce the C++ type notation from this type. */ std::string to_string () const; /** * @brief Gets the default value for the given type T * * The type T must be the one with which the type object * was initialized. */ template typename ArgSpec::init_type default_value () const { const ArgSpec *arg_spec = dynamic_cast *> (mp_spec); tl_assert (arg_spec != 0); return arg_spec->init (); } /** * @brief Gets the type code */ BasicType type () const { return m_type; } /** * @brief Sets the type code */ void set_type (BasicType t) { m_type = t; } /** * @brief Gets the specification object or 0 if there is none */ const ArgSpecBase *spec () const { return mp_spec; } /** * @brief Returns a value indicating that the ownership of a passed object is transfered to the receiver */ bool pass_obj () const { return m_pass_obj; } /** * @brief Sets a value indicating that the ownership of a passed object is transfered to the receiver */ void set_pass_obj (bool b) { m_pass_obj = b; } /** * @brief Returns a value indicating whether the type is a reference */ bool is_ref () const { return m_is_ref; } /** * @brief Sets a value indicating whether the type is a reference */ void set_is_ref (bool b) { m_is_ref = b; } /** * @brief Returns a value indicating whether the type is a pointer */ bool is_ptr () const { return m_is_ptr; } /** * @brief Sets a value indicating whether the type is a pointer */ void set_is_ptr (bool b) { m_is_ptr = b; } /** * @brief Returns a value indicating whether the type is a const reference */ bool is_cref () const { return m_is_cref; } /** * @brief Sets a value indicating whether the type is a const reference */ void set_is_cref (bool b) { m_is_cref = b; } /** * @brief Returns a value indicating whether the type is a const pointer */ bool is_cptr () const { return m_is_cptr; } /** * @brief Sets a value indicating whether the type is a const pointer */ void set_is_cptr (bool b) { m_is_cptr = b; } /** * @brief Returns a value indicating whether the type is an iterator */ bool is_iter () const { return m_is_iter; } /** * @brief Sets a value indicating whether the type is an iterator */ void set_is_iter (bool b) { m_is_iter = b; } /** * @brief Returns the size (in bytes) on the call stack */ unsigned int size () const { return m_size; } /** * @brief Returns the class descriptor if the type is an object */ const ClassBase *cls () const { return mp_cls; } /** * @brief Sets the class descriptor */ void set_cls (const ClassBase *cls) { mp_cls = cls; } /** * @brief Returns a pointer to the inner type (i.e. value type of an array) or 0 if there is no inner type */ const ArgType *inner () const { return mp_inner; } /** * @brief Returns a pointer to the inner key type (i.e. key type of an hash) or 0 if there is no inner type */ const ArgType *inner_k () const { return mp_inner_k; } private: BasicType m_type; const ArgSpecBase *mp_spec; ArgType *mp_inner, *mp_inner_k; bool m_is_ref : 1; bool m_is_ptr : 1; bool m_is_cref : 1; bool m_is_cptr : 1; bool m_is_iter : 1; bool m_owns_spec : 1; bool m_pass_obj : 1; mutable const ClassBase *mp_cls; unsigned int m_size; void release_spec (); }; struct GSI_PUBLIC IncompatibleTypeException : public tl::Exception { IncompatibleTypeException (const ArgType &got, const ArgType &want) : tl::Exception (tl::to_string (QObject::tr ("Incompatible types: got '")) + got.to_string () + tl::to_string (QObject::tr ("', want '")) + want.to_string () + "'") { } }; inline void ArgType::check_type (const ArgType &a) const { if (*this != a) { throw IncompatibleTypeException (a, *this); } } // --------------------------------------------------------------------------------- // Utility: determine non-case "base" of X (nc_x(const X) == X) template struct non_const_x { typedef X nc_x; }; template struct non_const_x { typedef X nc_x; }; // --------------------------------------------------------------------------------- // Utility: determine, if X is const template struct is_const_x { static bool value () { return false; } }; template struct is_const_x { static bool value () { return true; } }; // --------------------------------------------------------------------------------- // Utility: type dispatcher (enum to C++ type) template struct call_variadic_function { inline void operator() (const A1 *arg1, const A2 *arg2, const A3 *arg3, const A4 *arg4, const A5 *arg5) { F() (*arg1, *arg2, *arg3, *arg4, *arg5); } }; template struct call_variadic_function { inline void operator() (const A1 *arg1, const A2 *arg2, const A3 *arg3, const A4 *arg4, const void *) { F() (*arg1, *arg2, *arg3, *arg4); } }; template struct call_variadic_function { inline void operator() (const A1 *arg1, const A2 *arg2, const A3 *arg3, const void *, const void *) { F() (*arg1, *arg2, *arg3); } }; template struct call_variadic_function { inline void operator() (const A1 *arg1, const A2 *arg2, const void *, const void *, const void *) { F() (*arg1, *arg2); } }; template struct call_variadic_function { inline void operator() (const A1 *arg1, const void *, const void *, const void *, const void *) { F() (*arg1); } }; template struct call_variadic_function { inline void operator() (const void *, const void *, const void *, const void *, const void *) { F() (); } }; /** * @brief Represents "T_object" as a C++ type */ struct ObjectType { }; /** * @brief Represents "T_string" as a C++ type */ struct StringType { }; /** * @brief Represents "T_var" as a C++ type */ struct VariantType { }; /** * @brief Represents "T_vector" as a C++ type */ struct VectorType { }; /** * @brief Represents "T_map" as a C++ type */ struct MapType { }; /** * @brief Represents "T_void" as a C++ type */ struct VoidType { }; template class F, class A1, class A2, class A3, class A4, class A5> void do_on_type_impl (gsi::BasicType type, const A1 *arg1, const A2 *arg2, const A3 *arg3, const A4 *arg4, const A5 *arg5) { switch (type) { case gsi::T_bool: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_char: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_schar: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uchar: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_short: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ushort: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_int: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uint: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_long: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_longlong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulonglong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; #if defined(HAVE_64BIT_COORD) case gsi::T_int128: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; #endif case gsi::T_double: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_float: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void_ptr: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_string: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_var: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_object: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_vector: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_map: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; } } template class F, class A1, class A2, class A3, class A4, class A5> void do_on_type_impl_second (gsi::BasicType type, const A1 *arg1, const A2 *arg2, const A3 *arg3, const A4 *arg4, const A5 *arg5) { switch (type) { default: break; case gsi::T_bool: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_char: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_schar: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uchar: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_short: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ushort: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_int: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uint: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_long: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_longlong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulonglong: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; #if defined(HAVE_64BIT_COORD) case gsi::T_int128: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; #endif case gsi::T_double: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_float: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void_ptr: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_string: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_var: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_object: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_vector: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_map: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void: call_variadic_function, A1, A2, A3, A4, A5> () (arg1, arg2, arg3, arg4, arg5); break; } } template class F, class A1, class A2, class A3, class A4, class A5> void do_on_type_impl2 (gsi::BasicType type1, gsi::BasicType type2, const A1 *arg1, const A2 *arg2, const A3 *arg3, const A4 *arg4, const A5 *arg5) { switch (type1) { default: break; case gsi::T_bool: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_char: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_schar: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uchar: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_short: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ushort: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_int: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_uint: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_long: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulong: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_longlong: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_ulonglong: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; #if defined(HAVE_64BIT_COORD) case gsi::T_int128: do_on_type_impl_second<__int128, F, A1, A2, A3, A4, A5> (type2, arg1, arg2, arg3, arg4, arg5); break; #endif case gsi::T_double: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_float: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void_ptr: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_string: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_var: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_object: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_vector: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_map: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; case gsi::T_void: do_on_type_impl_second (type2, arg1, arg2, arg3, arg4, arg5); break; } } /** * @brief Another utility to map a type enum to a type * * Is must be used this way: * * template * struct func { * void operator() (int x, ...) { do_it_with_X; } // arguments can be any type * }; * * if (! do_on_type()(type, passed_as_arg1, ...)) { * do_it_with_other_types(type); * } */ template class F> struct do_on_type { template void operator() (gsi::BasicType type, const A1 &arg1) { do_on_type_impl (type, &arg1, 0, 0, 0, 0); } template void operator() (gsi::BasicType type, const A1 &arg1, const A2 &arg2) { do_on_type_impl (type, &arg1, &arg2, 0, 0, 0); } template void operator() (gsi::BasicType type, const A1 &arg1, const A2 &arg2, const A3 &arg3) { do_on_type_impl (type, &arg1, &arg2, &arg3, 0, 0); } template void operator() (gsi::BasicType type, const A1 &arg1, const A2 &arg2, const A3 &arg3, const A4 &arg4) { do_on_type_impl (type, &arg1, &arg2, &arg3, &arg4, 0); } template void operator() (gsi::BasicType type, const A1 &arg1, const A2 &arg2, const A3 &arg3, const A4 &arg4, const A5 &arg5) { do_on_type_impl (type, &arg1, &arg2, &arg3, &arg4, &arg5); } }; /** * @brief Another utility to map two type enums to two types (for maps for example) * * Is must be used this way: * * template * struct func { * void operator() (int x, ...) { do_it_with_X; } // arguments can be any type * }; * * if (! do_on_type2()(type1, type2, passed_as_arg1, ...)) { * do_it_with_other_types(type); * } */ template class F2> struct do_on_type2 { template void operator() (gsi::BasicType type1, gsi::BasicType type2, const A1 &arg1) { do_on_type_impl2 (type1, type2, &arg1, 0, 0, 0, 0); } template void operator() (gsi::BasicType type1, gsi::BasicType type2, const A1 &arg1, const A2 &arg2) { do_on_type_impl2 (type1, type2, &arg1, &arg2, 0, 0, 0); } template void operator() (gsi::BasicType type1, gsi::BasicType type2, const A1 &arg1, const A2 &arg2, const A3 &arg3) { do_on_type_impl2 (type1, type2, &arg1, &arg2, &arg3, 0, 0); } template void operator() (gsi::BasicType type1, gsi::BasicType type2, const A1 &arg1, const A2 &arg2, const A3 &arg3, const A4 &arg4) { do_on_type_impl2 (type1, type2, &arg1, &arg2, &arg3, &arg4, 0); } template void operator() (gsi::BasicType type1, gsi::BasicType type2, const A1 &arg1, const A2 &arg2, const A3 &arg3, const A4 &arg4, const A5 &arg5) { do_on_type_impl2 (type1, type2, &arg1, &arg2, &arg3, &arg4, &arg5); } }; } #endif