/* * variant.h * Copyright (C) 2010-2017 Belledonne Communications SARL * * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _VARIANT_H_ #define _VARIANT_H_ #include #include "linphone/utils/general.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE #define L_DECLARE_VARIANT_TYPES(FUNC) \ FUNC(int, Int, 1) \ FUNC(unsigned int, UnsignedInt, 2) \ FUNC(short, Short, 3) \ FUNC(unsigned short, UnsignedShort, 4) \ FUNC(long, Long, 5) \ FUNC(unsigned long, UnsignedLong, 6) \ FUNC(long long, LongLong, 7) \ FUNC(unsigned long long, UnsignedLongLong, 8) \ FUNC(char, Char, 9) \ FUNC(bool, Bool, 10) \ FUNC(double, Double, 11) \ FUNC(float, Float, 12) \ FUNC(std::string, String, 13) \ FUNC(void *, Generic, 14) #define L_DECLARE_VARIANT_ENUM_TYPE(TYPE, NAME, ID) NAME = ID, #define L_DECLARE_VARIANT_TRAIT_TYPE(TYPE, NAME, ID) \ template<> \ struct Variant::IdOfType { \ static const int id = ID; \ }; class VariantPrivate; class LINPHONE_PUBLIC Variant { public: enum Type { Invalid = 0, L_DECLARE_VARIANT_TYPES(L_DECLARE_VARIANT_ENUM_TYPE) MaxDefaultTypes }; Variant (); Variant (Type type); Variant (const Variant &src); Variant (Variant &&src); Variant (int value); Variant (unsigned int value); Variant (short value); Variant (unsigned short value); Variant (long value); Variant (unsigned long value); Variant (long long value); Variant (unsigned long long value); Variant (char value); Variant (bool value); Variant (double value); Variant (float value); Variant (const std::string &value); // void* constructor. Must be explicitly called. template::value>> Variant (T value) : Variant (Variant::createGeneric(value)) {} ~Variant (); bool operator!= (const Variant &variant) const; bool operator< (const Variant &variant) const; bool operator<= (const Variant &variant) const; Variant &operator= (const Variant &variant); Variant &operator= (Variant &&variant); bool operator== (const Variant &variant) const; bool operator> (const Variant &variant) const; bool operator>= (const Variant &variant) const; template void setValue (const T &value) { // Yeah, I'm crazy but it's useful to avoid code duplication. new(this) Variant(value); } template T getValue (bool *soFarSoGood = nullptr) const { constexpr int id = IdOfType::id; static_assert(id != Invalid, "Unable to get value of unsupported type."); T value; bool ok; getValue(id, static_cast(&value), &ok); if (soFarSoGood) *soFarSoGood = ok; return value; } bool isValid () const; void clear (); void swap (const Variant &variant); private: template struct IdOfType { static const int id = Invalid; }; void getValue (int type, void *value, bool *soFarSoGood) const; static Variant createGeneric (void *value); VariantPrivate *mPrivate = nullptr; L_DECLARE_PRIVATE(Variant); }; L_DECLARE_VARIANT_TYPES(L_DECLARE_VARIANT_TRAIT_TYPE); #undef L_DECLARE_VARIANT_TYPES #undef L_DECLARE_VARIANT_ENUM_TYPE #undef L_DECLARE_VARIANT_TRAIT_TYPE LINPHONE_END_NAMESPACE #endif // ifndef _VARIANT_H_