Variant Class

Posts 1–10 of 10 · Page 1 of 1
Variant Class
This is just something i decided to do one today when I was bored. Do whatever you want with it. I tried my best to put useful comments in the code but English is not my first language. The code is most likely quite messy, so i would recommend you looking it through before using it in a "real life" application, i have not tested it more than in the video. The class basically acts like a union for
the most common types, and it is really simple to add your own types and provide conversion for them to. This "union" provides conversion between all these basic types without to much hassle.

It supports conversion between: bool, char, char *, std::string, int, long, unsigned long, long long, float, double, Vector, List

For example:

Code:
    Variant var("-18.99");//Here a variant is created and assigned to the char array value "-18.99"
    std::cout << var.toStdString()<< std::endl;//Here the char array value will be converted to a std string
    std::cout << var.toInt64()<< std::endl;//Here the char array value will be converted to a int64/long long
    //since a long long can't hold decimals the .99 will be lost during the conversion
    std::cout << var.toDouble() << std::endl;//The char array will here be converted to a double, no data will be
    //lost during this conversion since a double can hold decimal values.
    std::cout << var.toULong() << std::endl;//When converted to a unsigned long alla data will be lost
    //and zero will be returned since unsigned values does not hold negative values
    std::cout  << var.canFullyConvertTo(Variant::Int64) << std::endl;//Here it checks
    //if no data will be lost during a conversion to a Int64(long long) it will return false since the decimals
    //in the char array will be lost

Header: Variant.h

Code:
#ifndef VARIANT_H
#define VARIANT_H

#include <sstream>
#include <string.h>
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <list>




typedef long long int64;//A long long is the same as a int64



class Variant
{
    //A class meant to make it easier to convert between basic types
    //and classes and various functions that fits in that category
public:
    Variant();//The user don't assign the variable in the creation of the class
    Variant(const int Val);//The user assigns the class to a integer
    Variant(const float Val);//The user assigns the class to a float
    Variant(const double Val);//The user assigns the class to a double
    Variant(const bool Val);//The user assings the class to a boolean
    Variant(const char Val);//The user assigns the class to a char
    Variant(const char * Val);//The user assigns the class to a char array/char pointer
    Variant(const std::string Val);//The user assigns the class to a std::string
    Variant(const unsigned long Val);//The user assigns the class to a unsigned long by default
    Variant(const int64);//The user assigns the class to a long long/int64
    Variant(const std::vector<Variant> val);//The user assigns the class to a vector
    Variant(const std::list<Variant> val);//The user assigns the class to list
    Variant(const std::map<const char*,Variant> val);//Assigns the variant to a map

    void operator = (const Variant Val);//Set the variant to another variant
    bool operator == (const Variant val);//Check if the current variant equals to another
    //Variant by the value and the type

    bool operator != (const Variant val);//If the Variants don't have the same value and or type return true
    //else false

    enum Types
    {
        //A enum to keep track of all the types and classes
        //the variant class supports convertion between
        Undefined = -1,
        Int,
        Float,
        Double,
        Int64,
        ULong,
        Bool,
        Char,
        CharArray,
        stdString,
        Vector,
        List,
        Map

    };

    int type();//Return the current type of the current Variant class



    //The conversion functions

    int toInt();//Try to return the Variant as a integer
    float toFloat();//Try to return the Variant as a float
    double toDouble();//Try to return the Variant as a double
    bool toBool();//Try to return the Variant as a bool
    char toChar();//Try to return the Variant as a char
    char * toCharArray();//Try to return the Variant as a char array
    unsigned long toULong();//Try to return the variant as a unsigned long
    std::string toStdString();//Try to return the variant as a std::string
    int64 toInt64();//Try to return the variant as a int64
    long long toLongLong();//Try to return the variant as a long,long / 64 bit integer
    std::vector<Variant> toVector();//Try to return the variant as vector
    std::list<Variant> toList();//Try to return the current variant as a list
    std::map<const char*, Variant> toMap();//Return the current variant as a map if the current type is map
    static int toInt(Variant val);
    static float toFloat(Variant val);
    static double toDouble(Variant val);
    static unsigned long toULong( Variant val);
    static int64 toInt64( Variant val);
    long long toLongLong(Variant val);
    static bool toBool(Variant val);
    static char toChar(Variant val);
    static char * toCharArray( Variant val);
    static std::string toStdString(Variant val);
    static std::vector<Variant> toVector(Variant val);
    static std::list<Variant> toList(Variant val);
    std::map<const char*,Variant> toMap(Variant val);
    static bool isTrue(Variant Var);//Check if a variant is true
    bool canCastTo(const Types type);//Wheater the variant can be cast/always be converted to a specefied type
    bool cast(int & val);//Cast the current variant to the integer the user passed
    bool cast(float & val);//Cast the current variant to the float the user passed
    bool cast(double &val);//Cast the current variant to the double the user passed
    bool cast(bool &val);//Cast the current variant to the bool the user passed
    bool cast(char &val);//Cast the current variant to the char the user passed
    bool cast(unsigned long & val);//Cast the current variant to the unsigned long the user passed
    bool cast(int64 & val);//Cast the current variant to the int64 the user passed
    bool canFullyConvertTo(const Types type);//Wheater the Variant can be converted to a type without losing any data
    //if it cans it returns true else it returns false
    int indexOf(Variant value,const unsigned int begin);//Find the first index of a certain value inside the variant
    int lastIndexOf(Variant value,const unsigned int begin);//Find the last reference of a certain value inside the variant
    bool contains(const Variant val);//Check if the Variant contains another value or not
    bool matchingValues(const Variant val);//If the type matches and
    //the value of the both Variants matches return true
    //else false
    bool matchingTypes(const Variant val);//If the current Variant and the variant passed
    //has the same type it will return true
    //else it will return false
    bool isUndefined();//If the current variant is undefined
    //return true else false
    bool isContainer();//Wheater the current variant is a container or not

    enum Error
    {
        Error_NoError  = 0,
        Error_UndefinedType,
        Error_UnknownError
    };

    void clear();//Clear the current variant
    void setProperty(const char * keyName,const Variant value);//Set or add a new property to the current variant
    Variant property(const char * key);//Return the variant at the key, if it exist
    bool setValue(const Variant val, const Types type);//Set the value of the current variant and set type of the current variant





private:

    Types currentType;//To keep track of the current type

    void setCurrentType(const Types type);//Update the current type

    struct Value
    {
        //A struct/containter to keep track to store
        //the current value
        int iVal;//To hold integer values
        float fVal;//To hold floating point values
        double dVal;//To hold double values
        unsigned long ulVal;//To hold unsigned long values
        int64 i64Val;//To hold the int64 values
        bool bVal;//To hold boolean values
        char cVal;//To hold char values
        char * strVal;//To hold char array values/ cstring values
        std::string stdStrVal;//Hold the stdstirng
        std::vector<Variant> vecVal;//To hold vectors
        std::list<Variant> listVal;//To hold lists
        std::map<const char *,Variant> mapVal;//To hold maps
    };

    Value currentValue;//To keep track of the current value

    std::map<const char *,const Variant> properties;//The map that will store all the properties of the current Variant

    bool isIntegerData();//Check if the current variant only contains data that can be converted to a integer
    bool isDecimalData();//Check if the current variant onlu contains data that can be converted to a decimal type such as float or double
    //can fully be converted to a number

    bool vecCompare(std::vector<Variant>,std::vector<Variant>);//Check if two vectors are the same
    bool listCompare(std::list<Variant>, std::list<Variant>);//Check if two lists are the same
    bool mapCompare(std::map<const char*,Variant>,std::map<const char*,Variant>);

    std::list<Variant> vecToList(std::vector<Variant> Vec);//Return a vector as list
    std::vector<Variant> listToVec(std::list<Variant> list);//Return the list as a vector

};


#endif // VARIANT_H
Code: Variant.cpp

Code:
#include "variant.h"

Variant::Variant()
{
    setCurrentType(Undefined);//The current type is undefined
    //since the user did not pass a type as the parameters

}

void Variant::setCurrentType(const Variant::Types type)
{
    currentType = type;//Set the current type to keep track of the current type
}


Variant::Variant(const int Val)
{
    //The user assigns the class to a integer
    setCurrentType(Int);//Set the current type to int
    currentValue.iVal = Val;//Set the integer value to the integer the user passed
}
Variant::Variant(const float Val)
{
    //The user assigns the class to a float
    setCurrentType(Float);//Set the current type to float
    currentValue.fVal = Val;//Set the floating point value to the float value the user passed
}

Variant::Variant(const double Val)
{
    //The user assigns the class to a double
    setCurrentType(Double);//Set the current type to a double
    currentValue.dVal = Val;//Set the double to the double the user passed
}
Variant::Variant(const bool Val)
{
    //The user assings the class to a boolean
    setCurrentType(Bool);//Set the current type to bool
    currentValue.bVal = Val;//Set the boolean value to boolean the user passed
}
Variant::Variant(const char Val)
{

    //The user assigns the class to a char
    setCurrentType(Char);//Set the current type to char
    currentValue.cVal = Val;//Set the char value to the value the user passed

}
Variant::Variant(const char * Val)
{
   //The user assigns the class to a char array/char pointer
    setCurrentType(CharArray);//Set the current type to a char array
    currentValue.strVal = (char*)Val;//Set the string value to the string value the user passed
}

Variant::Variant(const std::string Val)
{
    //The user assigns the current variant to a std::string
    setCurrentType(stdString);//Set the current type to std::string to keep track of the current type
    currentValue.stdStrVal = Val;//Set the current value to the value passed by the user
}

Variant::Variant(const unsigned long Val)
{
    //The user assigns the current Variant to a unsigned long
    setCurrentType(ULong);//To keep track of the current type
    currentValue.ulVal = Val;//Set the current value to the value of the ULong passed by the user

}

Variant::Variant(const int64 Val)
{
    //The user assigns the Variant to a int64/long long
    setCurrentType(Int64);
    currentValue.i64Val = Val;//Set the int 64
}

Variant::Variant(const std::vector<Variant> val)
{
    setCurrentType(Vector);//Set the current type to vector
    currentValue.vecVal = val;//Set the vector
}

Variant::Variant(const std::list<Variant> val)
{
    setCurrentType(List);
    currentValue.listVal = val;

}

Variant::Variant(const std::map<const char *, Variant> val)
{
    setCurrentType(Map);
    currentValue.mapVal = val;
}


void Variant::operator =(const Variant Var)
{

    this->currentType = Var.currentType;//Set the currentType to the type of the variant the user passed
    this->currentValue = Var.currentValue;//Set the currentValue to the value of the variant the user passed
    //Since the Variant can handle all the basic types
    //there is no need to create a new = operator for each type, when they all can be passed
    //via the variant in this function
}

int Variant::type()
{
    //Return the current type of the current value
    //so the user can check for different types
    return (int)currentType;
}

int Variant::toInt()
{
    //Try to return the Variant as a integer
    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
        return this->currentValue.iVal;//If the Variant is a integer just return it
        break;
    case  Float:
        return (int)this->currentValue.fVal;//If the variant is a float type it to a integer and return it
        break;
    case Double:
        return (int)this->currentValue.dVal;//If the variant is a double type it to a integer and return
        break;
    case ULong:
        return (int)this->currentValue.ulVal;//Return the integer version of the unsigned long
        break;

    case Int64:
        return (int)this->currentValue.i64Val;//Return the integer version of the int64
    case Bool:
        return (int)this->currentValue.bVal;//Type the boolean to a intger and return
        break;
    case Char:
    {

        std::stringstream stream;//Create a stringstream to hold the char value
        stream << this->currentValue.cVal;//Set the stringstream to the char value
        int Re = 0;//Create the return integer and set it to 0 to avoid undefined behaviour
        stream >> Re;//Input the stored char to the integer
        return Re;//Return the integer

    }
    break;
    case CharArray:
    {


        std::stringstream stream;//Create a stringstream to hold the char array
        stream << this->currentValue.strVal;//Set the stringstream to the char array
        int Re = 0;//Create the return integer and assign it to 0 to avoid undefiend behaviours
        stream >> Re;//Input the char array tp the integer
        return Re;//Return the integer

    }

    case stdString:
    {


            std::stringstream stream;
            stream << this->currentValue.stdStrVal;
            int Re = 0;//Create the return integer
            stream >> Re;//Input the string value to the integer
            return Re;//Return the integer

    }
    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

        break;
    case Undefined:
    {
        return 0;//Return -1 for failed
    }


    }
    }
    return 0;//Return -1 for failed
}



float Variant::toFloat()
{
    //Try to return the Variant as a float

    if(isDecimalData() || isIntegerData())
    {
    switch(this->currentType)
    {
    case Int:
        return (float)this->currentValue.iVal;//Type the integer to a float and return it
        break;
    case Float:
        return (float)this->currentValue.fVal;//Return the float value
        break;
    case Double:
        return (float)this->currentValue.dVal;//Type the double to a float and return it
        break;
    case ULong:
        return (float)this->currentValue.ulVal;
        break;
    case Int64:
        return (float)this->currentValue.i64Val;
        break;
    case Bool:
        return (float)this->currentValue.bVal;//Type the boolean to a float ad return it
        break;
    case Char:
    {

        std::stringstream stream;//Create a stringstream for the char
        stream << this->currentValue.cVal;//Set the stringstream to the char
        float Re = 0.0;//Create the return float
        stream >> Re;//Assign the float to the value of the stream
        return Re;//Return the float
    }
        break;

    case CharArray:
    {

        std::stringstream stream;//Create a stringstream for the char array
        stream << this->currentValue.strVal;//Assisgn the stream to the char array
        float Re = 0.0;//Create the return float
        stream >> Re;//Assign the float the value of the stream
        return Re;//Return the float value
    }
        break;

    case stdString:
    {
            std::stringstream stream;//Create a stringstream for the char array
            stream << this->currentValue.stdStrVal;//Assisgn the stream to the std::string
            float Re = 0.0;//Create the return float
            stream >> Re;//Assign the float the value of the stream
            return Re;//Return the float value
    }

        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
    {
        return (float)0;//Return -1 for error
    }
        break;
    }
    }



    return (float)0;
}


bool Variant::toBool()
{
    return isTrue(this->toCharArray());//If the variant is true it will return true else false
}

double Variant::toDouble()
{


    if(isDecimalData() || isIntegerData())
    {
    switch(this->currentType)
    {
    case Int:
        return (double)this->currentValue.iVal;//Type the integer to a double and return it
        break;
    case Float:
        return (double)this->currentValue.fVal;//Type the float to a double and return it
        break;
    case Double:
        return this->currentValue.dVal;//Return the double vba
        break;

    case ULong:
        return (double)this->currentValue.ulVal;
        break;
    case Int64:
        return (double)this->currentValue.i64Val;
    case Bool:

        return (double)this->currentValue.bVal;//Type the boolean to a double and return it
        break;
    case Char:
    {


        std::stringstream stream;//Create the stream that will store the char
        stream << this->currentValue.cVal;//Assign the stream to the char
        double Re = 0.0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the double value


    }
        break;

    case CharArray:
    {


        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.strVal;//Assign the stream to the char array
        double Re = 0.0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the double value
    }
        break;

    case stdString:
    {

        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.stdStrVal;//Assign the stream to the std::string
        double Re = 0.0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the double value
    }
        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;



    case Undefined:
    {
        return 0;//Return  0 failed
    }
        break;

    }
    }



    return 0;//Return 0 for failed
}

unsigned long Variant::toULong()
{

    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
        return (unsigned long)this->currentValue.iVal;
        break;
    case Float:
        return (unsigned long)this->currentValue.fVal;
        break;
    case Double:
        return (unsigned long)this->currentValue.dVal;
        break;
    case ULong:
        return this->currentValue.ulVal;
        break;
    case Int64:
        return (unsigned long)this->currentValue.i64Val;

    case Bool:
        return (unsigned long)this->currentValue.bVal;
        break;
    case Char:
    {

        std::stringstream stream;//Create the stream that will store the char
        stream << this->currentValue.cVal;//Assign the stream to the char
        unsigned long Re = 0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the ULong value

    }
        break;

    case CharArray:
    {

        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.strVal;//Assign the stream to the char array
        unsigned long Re = 0;//Create the return ulong
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the ulong
    }
        break;

    case stdString:
    {

        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.stdStrVal;//Assign the stream to the std::string
        unsigned long Re = 0;//Create the return ulong
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the ulong
    }
        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
        return 0;//Failed
        break;
    }
    }

    return 0;//Failed
}

int64 Variant::toInt64()
{

    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
    {
        return (int64)this->currentValue.iVal;
    }
        break;

    case Float:
    {
        return (int64)this->currentValue.fVal;
    }
        break;

    case Double:
    {
        return (int64)this->currentValue.dVal;
    }
        break;

    case ULong:
    {
        return (int64)this->currentValue.ulVal;
    }
        break;

    case Int64:
    {
        return this->currentValue.i64Val;
    }
        break;

    case Bool:
    {
        return (int64)this->currentValue.bVal;
    }
        break;

    case Char:
    {


            std::stringstream stream;
            stream << this->currentValue.cVal;
            int64 re = 0;
            stream >> re;
            return re;

    }
        break;

    case CharArray:
    {

            std::stringstream stream;
            stream << this->currentValue.strVal;
            int64 re = 0;
            stream >> re;
            return re;
    }
        break;

    case stdString:
    {


            std::stringstream stream;
            stream << this->currentValue.stdStrVal;
            int64 re = 0;
            stream >> re;
            return re;
    }
        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
        return 0;
        break;
    }
    }

    return 0;
}

long long Variant::toLongLong()
{
    return this->toInt64();
}

char * Variant::toCharArray()
{
    //Try to return the variant as a char array

    switch(this->currentType)
    {
    case Int:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.iVal;//Assign the stream to the integer value
        const char * re;//Create the return char array
        re  = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Float:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.fVal;//Assign the stream to the floating point value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Double:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.dVal;//Assign the stream to the double value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case ULong:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.ulVal;//Assign the stream to the unsigned long value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Int64:
    {
        std::stringstream stream;
        stream << this->currentValue.i64Val;
        const char * re;
        re = stream.str().c_str();
        return (char*)re;
    }

    case Bool:
    {
        if(this->currentValue.bVal == true)
            return (char*)"1";//Return one for true
        return (char*)"0";//Return zero for false
    }
        break;

    case  Char:
    {
       std::stringstream stream;//Create the stream to hold the char
       stream << this->currentValue.cVal;//Set the stream to the char
       return (char*)stream.str().c_str();//Return the stream as a char array
    }
        break;

    case CharArray:
        return (char*)this->currentValue.strVal;//Just return the char array
        break;

    case stdString:
    return (char*)this->currentValue.stdStrVal.c_str();//Return the char array version of the std::string
    break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
        return (char*)"";//Return nothing as for failed

    }


    return (char*)"";//Return nothing as for failed
}

bool Variant::isTrue(Variant Var)
{
    //Check if the passed variant is true or false
    const char * str = (const char*)Var.toCharArray();//Convert the variant to a cstring
    int strsize = strlen((const char*)str);//Get the lenght of the string

    int TCount = 0;//Too keep track of the number of true chars in the string
    int FCount = 0;//Too keep track of the number of false chars in the string

    for(int i = 0; i < strsize;++i)
    {
        //Loop through the entire string
        //And check each char if it is true or not
        if(str[i] == '0')
            ++FCount;//A new false char was found,increase the number of false chars
        else
            ++TCount;//Else it is a true char increase the number of true chars in the string
    }

    if(TCount > FCount)
        return true;//The string contained more true chars than false chars
    else if(FCount > TCount)
        return false;//The string contained more false chars than true chars

        //If it has gotten to this point TCount and FCount is the same value
        //then base boolean of the first char in the string
        if(str[0] == '0')
            return false;//The first char is false so then return false
        return true;//Else the first char is true so return true
}

char Variant::toChar()
{
    //Try to convert the current Variant to a char
    switch(this->currentType)
    {
    case Int:
    {
        std::stringstream stream;//Create the stringstream that will hold tje integer value
        stream << this->currentValue.iVal;//Assign the stream to the integer value
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char

    }
        break;

    case Float:
    {
        std::stringstream stream;//Create the stringstream that will hold the float valie
        stream << this->currentValue.fVal;//Assign the stream to the float value
        char Re = '0';//Create the return char
        stream >> Re;///Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case Double:
    {
        std::stringstream stream;//Create the stringstream that will hold the double
        stream << this->currentValue.dVal;//Assign the stream to the double
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case ULong:
    {
        std::stringstream stream;//Create the stringstream that will hold the double
        stream << this->currentValue.ulVal;//Assign the stream to the unsigned long value
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case Int64:
    {
        std::stringstream stream;
        stream << this->currentValue.i64Val;
        char Re = '0';
        stream >> Re;
        return Re;
    }
        break;
    case Bool:
    {
        if(this->currentValue.bVal == true)
            return (char)'1';//Return true
        return (char)'0';//Return false
    }
        break;

    case Char:
        return this->currentValue.cVal;//Just return the char value
        break;
    case CharArray:
    {
        if(strlen((const char*)this->currentValue.strVal) > 0)
            return (char)this->currentValue.strVal[0];//Return the first char of the string
        else
        {
            return (char)'0';
        }

    }
        break;

    case stdString:
    {
        if(this->currentValue.stdStrVal.size() > 0)
            return this->currentValue.stdStrVal.at(0);//Return the first char
        else
            return (char)'0';
    }

        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
    {
        return '0';//Return 0 for failed
    }
    }

    return (char)'0';//Return 0 for failed

}

std::string Variant::toStdString()
{
    switch(this->currentType)
    {
    case Int:
    {
        std::stringstream stream;
        stream << this->currentValue.iVal;
        return stream.str();
    }
        break;
    case Float:
    {
        std::stringstream stream;
        stream << this->currentValue.fVal;
        return stream.str();
    }
        break;

    case Double:
    {
        std::stringstream stream;
        stream << this->currentValue.dVal;
        return stream.str();
    }
        break;

    case ULong:
    {
        std::stringstream stream;
        stream << this->currentValue.ulVal;
        return stream.str();
    }
        break;

    case Int64:
    {
        std::stringstream stream;
        stream << this->currentValue.i64Val;
        return stream.str();
    }
        break;

    case Bool:
    {
        if(this->currentValue.bVal == true)
            return "1";
        return "0";
    }
        break;

    case Char:
    {
        std::stringstream stream;
        stream << this->currentValue.cVal;
        return stream.str();
    }
        break;

    case CharArray:
    {
        return (std::string)this->currentValue.strVal;
    }
        break;

    case stdString:
    {
        return this->currentValue.stdStrVal;
    }
        break;

    case Vector:
        return 0;
        break;
    case List:
        return 0;
        break;
    case Map:
        return 0;
        break;

    case Undefined:
    {
        return (std::string)"0";
    }
        break;

    default:
        return (std::string)"0";
        break;
    }

    return "0";
}

std::vector<Variant> Variant::toVector()
{
        if(this->currentType == Vector)
            return this->currentValue.vecVal;
        else if(this->currentType == List)
        {
            return listToVec(currentValue.listVal);
        }
            return std::vector<Variant>();//Return a undefined vector
}


std::list<Variant> Variant::toList()
{
    if(currentType == List)
        return currentValue.listVal;
    else if(currentType == Vector)
    {
        return vecToList(currentValue.vecVal);//Return the vector as  list
    }

    return std::list<Variant>();//Return a undefined list
}

std::map<const char*,Variant> Variant::toMap()
{
    //Maps can only be converted to maps
    if(currentType == Map)
        return currentValue.mapVal;//Return the map if the current type is map
    return std::map<const char*, Variant>();//Return a empty map
}



int Variant::toInt(Variant val)
{
    return val.toInt();
}

float Variant::toFloat(Variant val)
{
    return val.toFloat();
}

double Variant::toDouble(Variant val)
{
    return val.toDouble();
}

unsigned long Variant::toULong(Variant val)
{
    return val.toULong();
}

int64 Variant::toInt64(Variant val)
{
    return val.toInt64();
}

long long Variant::toLongLong(Variant val)
{
    return val.toInt64();
}


bool Variant::toBool(Variant val)
{
    return val.toBool();
}

char Variant::toChar(Variant val)
{
    return val.toChar();
}

char * Variant::toCharArray(Variant val)
{
    return val.toCharArray();
}

std::string Variant::toStdString(Variant val)
{
    return val.toStdString();
}

std::vector<Variant> Variant::toVector(Variant val)
{
    return val.toVector();
}

std::list<Variant> Variant::toList(Variant val)
{
    return val.toList();
}

std::map<const char*, Variant> Variant::toMap(Variant val)
{
    return val.toMap();
}




void Variant::clear()
{
    //Clear all the Variants values
    currentValue.iVal = 0;//Set the integer value to zero
    currentValue.fVal = 0;//Set the float value to zero
    currentValue.dVal = 0;//Set the double value to zero
    currentValue.cVal = (char)(int)0;//Set the char value to null
    currentValue.ulVal = 0;
    currentValue.i64Val = 0;
    currentValue.stdStrVal = "";
    currentValue.strVal = (char*)"";//Set the string value to empty
    currentValue.bVal = false;//Set the boolean value to false
    currentValue.vecVal  = std::vector<Variant>();
    currentValue.listVal = std::list<Variant>();
    currentValue.mapVal = std::map<const char *, Variant>();
    setCurrentType(Undefined);//Set the current type to undefined
    //no type has been set by the user yet
}

bool Variant::canCastTo(const Variant::Types type)
{
    //Check if the current variant can be casted
    //to another type
    if(this->currentType == Char || this->currentType == Int
            || this->currentType == Float || this->currentType == Double || this->currentType == Bool || this->currentType == ULong || this->currentType == Int64)
    {
        //If the current Variant is any of these types
        return (type == Char || type == Int || type == Float || type == Double || type == Bool || type == ULong || type == Int64);

    }

    //The remaning type is the char array which can't be casted with anything
    return false;//therefore return false for not can be casted with the type the user passed
}

bool Variant::cast(int & val)
{

    switch(this->currentType)
    {
    case Int:
        val = (int)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (int)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (int)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (int)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (int)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;
    case stdString:
        return false;
        break;

    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;

    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(int64 & val)
{
    //Cast the current variant to a 64 bit integer
    switch(this->currentType)
    {
    case Int:
        val = (int64)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (int64)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (int64)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (int64)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = this->currentValue.i64Val;
        return true;
        break;
    case Char:
        val = (int64)this->currentValue.cVal;
        return true;
        break;
    case Bool:
        val = (int64)this->currentValue.bVal;
        return true;
        break;
    case CharArray:
        return false;
        break;
    case stdString:
        return false;
        break;
    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;

    case Undefined:
        return false;
        break;
    }

    return false;
}

bool Variant::cast(unsigned long & val)
{

    switch(this->currentType)
    {
    case Int:
        val = (unsigned long)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (unsigned long)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (unsigned long)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (unsigned long)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (unsigned long)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (unsigned long)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (unsigned long)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;
    case stdString:
        return false;
        break;
    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;

    case Undefined:
        return false;
        break;
    }

    return false;
}

bool Variant::cast(float & val)
{

    switch(this->currentType)
    {
    case Int:
        val = (float)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (float)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (float)this->currentValue.dVal;
        return true;
        break;

    case ULong:
        val = (float)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (float)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (float)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (float)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;
    case stdString:
        return false;
        break;

    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(double & val)
{
    switch(this->currentType)
    {
    case Int:
        val = (double)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (double)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (double)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (double)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (double)this->currentValue.i64Val;
        return true;
        break;

    case Bool:
        val = (double)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (double)this->currentValue.cVal;
        return true;
        break;
    case CharArray:
        return false;
        break;
    case stdString:
        return false;
        break;
    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(char & val)
{

    switch(this->currentType)
    {
    case Int:
        val = (char)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (char)(int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (char)(int)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (char)(int)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (char)(int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (char)(int)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (char)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;

    case stdString:
        return false;
        break;
    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}


bool Variant::cast(bool &val)
{
    switch(this->currentType)
    {
    case Int:
        val = (bool)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (bool)(int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (bool)(int)this->currentValue.dVal;
        return true;
        break;

    case ULong:
        val = (bool)(int)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (bool)(int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (bool)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (bool)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;

    case stdString:
        return false;
        break;
    case Vector:
        return false;
        break;
    case List:
        return false;
        break;
    case Map:
        return  false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::canFullyConvertTo(const Types T)
{
//    //A function meant for checking if the Variant can
//    //be converted to a type without losing any data

    //Since no data should ever be lost during a to std::string conversion
    //it can be used to check if the value somehow changed
    Variant check;//Create a variant to keep track of the value
    if(check.setValue(this->toStdString(),T))
    {//Set the value to the current to std::string since no data should be lost
    //and convert the string to whatever type the user entered
    return (check.toStdString() == this->toStdString());
    //If the two strings is the same no data was lost during the conversion and
    //true will be returned for can fully convert to
    //If the string are not the same data was lost and false will be returned
    }

    return false;//Return false for the value could not be set
}

int Variant::indexOf(Variant value, const unsigned int begin)
{
    //Find the first index of a ceratin value inside
    //this current variant from the begin posistion
    //if no one is found or it failed is someway return -1
    if(!isContainer())
    {
    const std::string str = toStdString();//The current Variant as a std::string
    const std::string refstr = value.toStdString();//The reference value as a std::string
    if(begin < str.size() && begin >= 0)//Just a basic overflow and underflow check
    {
    for(int i = 0; i + begin + refstr.size() <= str.size();++i)
    {
        //Loop through all the different possible substrings, that matches the lenght of the reference string
        if(str.substr(begin + i,refstr.size()) == refstr)
            return i;//The start posistion of the reference string was found from the begin point
    }
    }
    }

    return -1;//Return -1 for not found
}

int Variant::lastIndexOf(Variant value, const unsigned int begin)
{
    //Find the flst index of a certain value inside the Variant
    //begining from the begin posistion


    //To avoid overflows and underflows
    if(!isContainer())
    {
    const std::string str = toStdString();//The string representatiob of the Variant
    const std::string refstr = value.toStdString();//The string representation of the value to find
    if(begin < str.size() && begin >= 0)//Just basic overflow and underflow check
    {
    unsigned int lastIndex =  -1;//The integer that will keep track of the last found index
    //if non is found the value will stay at -1 and will return false

    for(int i = 0; i + begin + refstr.size() <= str.size();++i)
    {
        //Loop through all the different possible substrings, that matches the lenght of the reference string
        if(str.substr(begin + i,refstr.size()) == refstr)
            lastIndex = i;//The start posistion of the reference string was found from the begin point
    }
   return lastIndex;//If the value was found somewhere inside the Variant a value bigger than -1 will be returned
   //else -1 will be returned for failed
    }
    }

    return -1;//The user entered a value to either to small or to big, and -1 is returned for failed
}

bool Variant::contains(const Variant val)
{
    //If the current variant contains the value
    //of val true will be returned, otherwise false
    if(this->indexOf(val,0) > -1)
        return true;//The value was found inside the variant
    return false;//It was not found inside the variant
}

bool Variant::setValue(Variant val, const Types T)
{
    //Set the Variant value without changing the T

    setCurrentType(T);
    if(currentType == T)
    {//If the current type actually was set
    switch(T)
    {
    case Int:
        this->currentValue.iVal = val.toInt();
        return true;
        break;
    case Float:
        this->currentValue.fVal = val.toFloat();
        return true;
        break;
    case Double:
        this->currentValue.dVal = val.toDouble();
        return true;
        break;
    case ULong:
        this->currentValue.ulVal = val.toULong();
        return true;
        break;       
    case Int64:
        this->currentValue.i64Val = val.toInt64();
        return true;
        break;
    case Bool:
        this->currentValue.bVal = val.toBool();
        return true;
        break;
    case Char:
        this->currentValue.cVal = val.toChar();
        return true;
        break;
    case CharArray:
        this->currentValue.strVal = val.toCharArray();
        return true;
        break;

    case stdString:
        this->currentValue.stdStrVal = val.toStdString();
        return true;
        break;
    case Vector:
        this->currentValue.vecVal = val.toVector();
        return true;
        break;
    case List:
        this->currentValue.listVal = val.toList();
        return true;
        break;
    case Map:
        this->currentValue.mapVal = val.toMap();
        return true;
        break;
    case Undefined:
        this->clear();//Clear the current variant/undefine it
        return true;
        break;

    default:
        return false;
        break;
    }
    }

    return false;//Return false for failed
}

bool Variant::operator ==(const Variant val)
{
return matchingValues(val);//Check if the values and the types are the same
}

bool Variant::matchingTypes(const Variant val)
{
    return (this->currentType ==  val.currentType);
}

bool Variant::matchingValues(Variant val)
{
    if(matchingTypes(val))
    {
        //The types must be the same for the value to match
        switch(this->currentType)
        {
        case Int:
        {
            return (this->currentValue.iVal == val.currentValue.iVal);

        }
            break;

        case Float:
        {
            return (this->currentValue.fVal == val.currentValue.fVal);

        }
            break;

        case Double:
        {
            return (this->currentValue.dVal == val.currentValue.dVal);
        }
            break;

        case ULong:
        {
            return (this->currentValue.ulVal == val.currentValue.ulVal);
        }
            break;

        case Int64:
        {
            return (this->currentValue.i64Val == val.currentValue.i64Val);
        }
            break;

        case Bool:
        {
            return (this->currentValue.bVal == val.currentValue.bVal);
        }
            break;

        case Char:
        {
            return (this->currentValue.cVal == val.currentValue.cVal);
        }
            break;

        case CharArray:
        {
            return (this->currentValue.strVal == val.currentValue.strVal);
        }
            break;

        case stdString:
        {
            return (this->currentValue.stdStrVal == val.currentValue.stdStrVal);
        }
            break;

        case Vector:
        {
             return vecCompare(this->currentValue.vecVal,val.currentValue.vecVal);
        }
            break;

        case List:
        {
            return listCompare(this->currentValue.listVal,val.currentValue.listVal);
        }
            break;

        case Map:
        {
            return mapCompare(this->currentValue.mapVal,val.currentValue.mapVal);
        }
            break;


        case Undefined:
           return true;//Both the variants are undefined
           break;

    }

    }

    return false;
}

bool Variant::operator !=(const Variant val)
{
    //Check if the current variant and the passed variant
    //don't have the same value and or type
    return (!matchingValues(val));
}


bool Variant::isUndefined()
{
    return (currentType == Undefined);
}

void Variant::setProperty(const char * keyName,const Variant value)
{
    //Add a new property with the keyName as the key and the Variant as the value
    properties.insert(std::pair<const char*,const Variant>(keyName,value));
}

Variant Variant::property(const char *key)
{
    //Return the value of the key from key of it
    Variant re;//Create a undefined variant
    std::map<const char*,const Variant>::const_iterator iter = properties.find(key);
    if(iter != properties.end())
    {
        //If the key was found
        //the matching value can be returned
       re = iter->second;//Set the variant to the value of the key
    }

    return re;//If the key and value was not found a undefined variant will be returned
}

bool Variant::isContainer()
{

    return (currentType == Vector || currentType == List || currentType == Map);
}

bool Variant::vecCompare(std::vector<Variant>  v1,  std::vector<Variant>  v2)
{
    return (v1.size() == v2.size()) && std::equal(v1.begin(),v1.end(),v2.begin());
}

bool Variant::listCompare(std::list<Variant> L1, std::list<Variant> L2)
{
    return (L1.size() == L2.size()) && std::equal(L1.begin(),L1.end(),L2.begin());
}

bool Variant::mapCompare(std::map<const char *, Variant> m1, std::map<const char *, Variant> m2)
{
    if(m1.size() != m2.size())
        return false;

    std::map<const char*, Variant>::iterator iter1 = m1.begin(), iter2 = m2.begin();


    while(iter1 != m1.end() && iter2 != m2.end())
    {

        if(iter1->first != iter2->first)return false;
        if(iter1->second != iter2->second)return false;

        ++iter1;
        ++iter2;
    }

    return true;//The both maps are the same
}

std::list<Variant> Variant::vecToList(std::vector<Variant> Vec)
{
    //Convert a vector to a list
    return std::list<Variant>(Vec.begin(),Vec.end());//Fill the list with the data fof the vector
}

std::vector<Variant> Variant::listToVec(std::list<Variant> List)
{
    //Convert a List to vector
    return std::vector<Variant>(List.begin(),List.end());//Fill the vector with the data of the list
}

bool Variant::isIntegerData()
{
    //Check if the current Variant only contains data that can be converted to a integer type
    //Only for private usage since it might
    if(isContainer())
        return false;//If the Variant has the type of a container it can't be converted to any integer type
    if(currentType == Int || currentType == ULong || currentType == Int64)
        return true;

    const std::string check = toStdString();//Convert the current variant to a std::string since
    //no data should be lost during that conversion
    for(unsigned int i = 0; i < check.size();++i)
        if((int)(char)check.at(i) < 48 || (int)(char)check.at(i) > 57)
        {
            if(i > 0 && (int)(char)check.at(i) != 45)
                return false;

        }
    return true;//The integer only contains data that can be converted to a integer
}

bool Variant::isDecimalData()
{
    //Check if the current variant only contains data that can be converted to float or double data
    if(isContainer())
        return false;
    else if(currentType == Float || currentType == Double)
        return true;
    const std::string check = toStdString();
    for(unsigned int i = 0; i < check.size();++i)
        if((int)(char)check.at(i) < 48 || (int)(char)check.at(i) > 57)
        {
            if(i == 0 && (int)(char)check.at(i) == 45);//Check if it is negative mark
            else if(i == 0 || i == check.size() - 1 || (int)(char)check.at(i) != 46)//Check if it is not a decimal value
                return false;
        }
    return true;
}
What exactly is it for, I can't be fucked reading all that code.
It is like a container that can store the most common types and makes it easy to convert between all the supported types. It kind of acts like a union for the most common types. Just read the header and you will understand what it does.

Example:

Code:
Variant var((std::string)"189.89");

double dVal = var.toDouble();//Will convert the std::string to a double

var = (int64)189888;
const char * cVal = var.toCharArray();//Wil convert the variant that now contains the long long value 189888 to a char array/ cstring.
Example 2:

Code:
void printStuff(Variant val)
{
  std::cout << val.toStdString();
}

//You can now call that print function with the most common types.

printStuff((double)189.89);
printStuff((bool)false);
Quote Originally Posted by Variant View Post
It is like a container that can store the most common types and makes it easy to convert between all the supported types. It kind of acts like a union for the most common types.

Example:

Variant var((std::string)"189.89");

double dVal = var.toDouble();//Will convert the std::string to a double

var = (int64)189888;
const char * cVal = var.toCharArray();//Wil convert the variant that now contains the long long value 189888 to a char array/ cstring.
Seems like a lot of effort to me :/
What do you mean? It is a very simple class the code is just very repetitive since i didn't use templates. Look up the boost libraries Variant class if you are confused.
I'm not confused lol, I just meant it seems like such a waste of time to spend so long writing all that repetitive code when chances are you won't need to use this sort of functionality much at all :/
It did not take more than an hour, but i get what you are saying.
This is actually really nice, good job!
Great work
Thanks, good start! I was looking for a simple Variant class not using templates as it will be used across module boundaries e.g. exe <-> dll.

Now, I'm a bit of a C++ novice, but my knowledge has grown perhaps 10 fold in last week due to reading a great book and trying to build a reasonably complex library.

Attached is updated code where I just support basic types. Key differences to note are that I qualify const functions (i.e. ones that don't change anything), and pass everything by reference as possible if non basic type.

Also made copies of CharArray (char *) when setting value - debugging issues around mismatched object lifetime can be painful.

I'll likely continue to update this code as it will be publicly used by consumers of the library.

Cheers
Code:
#ifndef VARIANT_H
#define VARIANT_H

#include <sstream>
#include <string.h>
#include <iostream>
typedef long long int64;//A long long is the same as a int64

class Variant
{
    //A class meant to make it easier to convert between basic types
    //and classes and various functions that fits in that category
public:
    Variant();//The user don't assign the variable in the creation of the class
	Variant(const Variant& val);
    Variant(const int Val);//The user assigns the class to a integer
    Variant(const float Val);//The user assigns the class to a float
    Variant(const double Val);//The user assigns the class to a double
    Variant(const bool Val);//The user assings the class to a boolean
    Variant(const char Val);//The user assigns the class to a char
    Variant(const char * Val);//The user assigns the class to a char array/char pointer
    Variant(const unsigned long Val);//The user assigns the class to a unsigned long by default
    Variant(const int64);//The user assigns the class to a long long/int64
	~Variant();
    void operator = (const Variant& Val);//Set the variant to another variant
    bool operator == (const Variant& val) const;//Check if the current variant equals to another
    //Variant by the value and the type

    bool operator != (const Variant& val) const;//If the Variants don't have the same value and or type return true
    //else false

    enum Types
    {
        //A enum to keep track of all the types and classes
        //the variant class supports convertion between
        Undefined = -1,
        Int,
        Float,
        Double,
        Int64,
        ULong,
        Bool,
        Char,
        CharArray

    };

    int type() const;//Return the current type of the current Variant class



    //The conversion functions

    int toInt() const;//Try to return the Variant as a integer
    float toFloat() const;//Try to return the Variant as a float
    double toDouble() const;//Try to return the Variant as a double
    bool toBool() const;//Try to return the Variant as a bool
    char toChar() const;//Try to return the Variant as a char
    const char * toCharArray() const;//Try to return the Variant as a char array
    unsigned long toULong() const;//Try to return the variant as a unsigned long
    int64 toInt64() const;//Try to return the variant as a int64
    long long toLongLong() const;//Try to return the variant as a long,long / 64 bit integer
    static int toInt(const Variant& val);
    static float toFloat(const Variant& val);
    static double toDouble(const Variant& val);
    static unsigned long toULong(const Variant& val);
    static int64 toInt64(const Variant& val);
    long long toLongLong(const Variant& val);
    static bool toBool(const Variant& val);
    static char toChar(const Variant& val);
    static const char * toCharArray( const Variant& val);
    static bool isTrue(const Variant& Var);//Check if a variant is true
    bool canCastTo(const Types type) const;//Wheater the variant can be cast/always be converted to a specefied type
    bool cast(int val);//Cast the current variant to the integer the user passed
    bool cast(float val);//Cast the current variant to the float the user passed
    bool cast(double val);//Cast the current variant to the double the user passed
    bool cast(bool val);//Cast the current variant to the bool the user passed
    bool cast(char val);//Cast the current variant to the char the user passed
    bool cast(unsigned long val);//Cast the current variant to the unsigned long the user passed
    bool cast(int64 val);//Cast the current variant to the int64 the user passed
    bool matchingValues(const Variant &val) const; //If the type matches and
    //the value of the both Variants matches return true
    //else false
    bool matchingTypes(const Variant &val) const;//If the current Variant and the variant passed
    //has the same type it will return true
    //else it will return false
    bool isUndefined() const;//If the current variant is undefined
    //return true else false
    enum Error
    {
        Error_NoError  = 0,
        Error_UndefinedType,
        Error_UnknownError
    };

    void clear();//Clear the current variant
    bool setValue(const Variant &val, const Types type);//Set the value of the current variant and set type of the current variant





private:

    Types currentType;//To keep track of the current type

    void setCurrentType(const Types type);//Update the current type

    union Value
    {
        //A struct/containter to keep track to store
        //the current value
        int iVal;//To hold integer values
        float fVal;//To hold floating point values
        double dVal;//To hold double values
        unsigned long ulVal;//To hold unsigned long values
        int64 i64Val;//To hold the int64 values
        bool bVal;//To hold boolean values
        char cVal;//To hold char values
        char * strVal;//To hold char array values/ cstring values
    };

    Value currentValue;//To keep track of the current value

    bool isIntegerData() const;//Check if the current variant only contains data that can be converted to a integer
    bool isDecimalData() const;//Check if the current variant onlu contains data that can be converted to a decimal type such as float or double
    //can fully be converted to a number


};

#endif // VARIANT_H
Code:
#include "variant.h"

Variant::Variant()
{
	currentValue.strVal = NULL;
    setCurrentType(Undefined);//The current type is undefined
    //since the user did not pass a type as the parameters

}

Variant::Variant(const Variant &val)
{
	setValue(val, val.currentType);
}

Variant::~Variant()
{
	setCurrentType(Undefined);

}
void Variant::setCurrentType(const Variant::Types type)
{
	if ( currentType != CharArray )
		currentValue.strVal = NULL;

	if ( currentType == CharArray && currentValue.strVal)
	{
		free(currentValue.strVal);
		currentValue.strVal = NULL;
	}
    currentType = type;//Set the current type to keep track of the current type
}


Variant::Variant(const int Val)
{
    //The user assigns the class to a integer
    setCurrentType(Int);//Set the current type to int
    currentValue.iVal = Val;//Set the integer value to the integer the user passed
}
Variant::Variant(const float Val)
{
    //The user assigns the class to a float
    setCurrentType(Float);//Set the current type to float
    currentValue.fVal = Val;//Set the floating point value to the float value the user passed
}

Variant::Variant(const double Val)
{
    //The user assigns the class to a double
    setCurrentType(Double);//Set the current type to a double
    currentValue.dVal = Val;//Set the double to the double the user passed
}
Variant::Variant(const bool Val)
{
    //The user assings the class to a boolean
    setCurrentType(Bool);//Set the current type to bool
    currentValue.bVal = Val;//Set the boolean value to boolean the user passed
}
Variant::Variant(const char Val)
{

    //The user assigns the class to a char
    setCurrentType(Char);//Set the current type to char
    currentValue.cVal = Val;//Set the char value to the value the user passed

}
Variant::Variant(const char * Val)
{
    //The user assigns the class to a char array/char pointer
    setCurrentType(CharArray);//Set the current type to a char array
    currentValue.strVal = _strdup(Val);//Set the string value to the string value the user passed
}


Variant::Variant(const unsigned long Val)
{
    //The user assigns the current Variant to a unsigned long
    setCurrentType(ULong);//To keep track of the current type
    currentValue.ulVal = Val;//Set the current value to the value of the ULong passed by the user

}

Variant::Variant(const int64 Val)
{
    //The user assigns the Variant to a int64/long long
    setCurrentType(Int64);
    currentValue.i64Val = Val;//Set the int 64
}


void Variant::operator =(const Variant &Var)
{
	setValue(Var, Var.currentType);
    // this->currentType = Var.currentType;//Set the currentType to the type of the variant the user passed
    // this->currentValue = Var.currentValue;//Set the currentValue to the value of the variant the user passed
    //Since the Variant can handle all the basic types
    //there is no need to create a new = operator for each type, when they all can be passed
    //via the variant in this function
}

int Variant::type() const
{
    //Return the current type of the current value
    //so the user can check for different types
    return (int)currentType;
}

int Variant::toInt() const
{
    //Try to return the Variant as a integer
    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
        return this->currentValue.iVal;//If the Variant is a integer just return it
        break;
    case  Float:
        return (int)this->currentValue.fVal;//If the variant is a float type it to a integer and return it
        break;
    case Double:
        return (int)this->currentValue.dVal;//If the variant is a double type it to a integer and return
        break;
    case ULong:
        return (int)this->currentValue.ulVal;//Return the integer version of the unsigned long
        break;

    case Int64:
        return (int)this->currentValue.i64Val;//Return the integer version of the int64
    case Bool:
        return (int)this->currentValue.bVal;//Type the boolean to a intger and return
        break;
    case Char:
    {

        std::stringstream stream;//Create a stringstream to hold the char value
        stream << this->currentValue.cVal;//Set the stringstream to the char value
        int Re = 0;//Create the return integer and set it to 0 to avoid undefined behaviour
        stream >> Re;//Input the stored char to the integer
        return Re;//Return the integer

    }
    break;
    case CharArray:
    {


        std::stringstream stream;//Create a stringstream to hold the char array
        stream << this->currentValue.strVal;//Set the stringstream to the char array
        int Re = 0;//Create the return integer and assign it to 0 to avoid undefiend behaviours
        stream >> Re;//Input the char array tp the integer
        return Re;//Return the integer

    }

    case Undefined:
    {
        return 0;//Return -1 for failed
    }


    }
    }
    return 0;//Return -1 for failed
}



float Variant::toFloat() const
{
    //Try to return the Variant as a float

    if(isDecimalData() || isIntegerData())
    {
    switch(this->currentType)
    {
    case Int:
        return (float)this->currentValue.iVal;//Type the integer to a float and return it
        break;
    case Float:
        return (float)this->currentValue.fVal;//Return the float value
        break;
    case Double:
        return (float)this->currentValue.dVal;//Type the double to a float and return it
        break;
    case ULong:
        return (float)this->currentValue.ulVal;
        break;
    case Int64:
        return (float)this->currentValue.i64Val;
        break;
    case Bool:
        return (float)this->currentValue.bVal;//Type the boolean to a float ad return it
        break;
    case Char:
    {

        std::stringstream stream;//Create a stringstream for the char
        stream << this->currentValue.cVal;//Set the stringstream to the char
        float Re = 0.0;//Create the return float
        stream >> Re;//Assign the float to the value of the stream
        return Re;//Return the float
    }
        break;

    case CharArray:
    {

        std::stringstream stream;//Create a stringstream for the char array
        stream << this->currentValue.strVal;//Assisgn the stream to the char array
        float Re = 0.0;//Create the return float
        stream >> Re;//Assign the float the value of the stream
        return Re;//Return the float value
    }
        break;

    case Undefined:
    {
        return (float)0;//Return -1 for error
    }
        break;
    }
    }



    return (float)0;
}


bool Variant::toBool() const
{
    return isTrue(this->toCharArray());//If the variant is true it will return true else false
}

double Variant::toDouble() const
{


    if(isDecimalData() || isIntegerData())
    {
    switch(this->currentType)
    {
    case Int:
        return (double)this->currentValue.iVal;//Type the integer to a double and return it
        break;
    case Float:
        return (double)this->currentValue.fVal;//Type the float to a double and return it
        break;
    case Double:
        return this->currentValue.dVal;//Return the double vba
        break;

    case ULong:
        return (double)this->currentValue.ulVal;
        break;
    case Int64:
        return (double)this->currentValue.i64Val;
    case Bool:

        return (double)this->currentValue.bVal;//Type the boolean to a double and return it
        break;
    case Char:
    {


        std::stringstream stream;//Create the stream that will store the char
        stream << this->currentValue.cVal;//Assign the stream to the char
        double Re = 0.0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the double value


    }
        break;

    case CharArray:
    {


        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.strVal;//Assign the stream to the char array
        double Re = 0.0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the double value
    }
        break;

    case Undefined:
    {
        return 0;//Return  0 failed
    }
        break;

    }
    }



    return 0;//Return 0 for failed
}

unsigned long Variant::toULong() const
{

    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
        return (unsigned long)this->currentValue.iVal;
        break;
    case Float:
        return (unsigned long)this->currentValue.fVal;
        break;
    case Double:
        return (unsigned long)this->currentValue.dVal;
        break;
    case ULong:
        return this->currentValue.ulVal;
        break;
    case Int64:
        return (unsigned long)this->currentValue.i64Val;

    case Bool:
        return (unsigned long)this->currentValue.bVal;
        break;
    case Char:
    {

        std::stringstream stream;//Create the stream that will store the char
        stream << this->currentValue.cVal;//Assign the stream to the char
        unsigned long Re = 0;//Create the return double
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the ULong value

    }
        break;

    case CharArray:
    {

        std::stringstream stream;//Create the stream that will store the char array
        stream << this->currentValue.strVal;//Assign the stream to the char array
        unsigned long Re = 0;//Create the return ulong
        stream >> Re;//Assign the double to the value of the stream
        return Re;//Return the ulong
    }
        break;

    case Undefined:
        return 0;//Failed
        break;
    }
    }

    return 0;//Failed
}

int64 Variant::toInt64() const
{

    if(isIntegerData() || isDecimalData())
    {
    switch(this->currentType)
    {
    case Int:
    {
        return (int64)this->currentValue.iVal;
    }
        break;

    case Float:
    {
        return (int64)this->currentValue.fVal;
    }
        break;

    case Double:
    {
        return (int64)this->currentValue.dVal;
    }
        break;

    case ULong:
    {
        return (int64)this->currentValue.ulVal;
    }
        break;

    case Int64:
    {
        return this->currentValue.i64Val;
    }
        break;

    case Bool:
    {
        return (int64)this->currentValue.bVal;
    }
        break;

    case Char:
    {


            std::stringstream stream;
            stream << this->currentValue.cVal;
            int64 re = 0;
            stream >> re;
            return re;

    }
        break;

    case CharArray:
    {

            std::stringstream stream;
            stream << this->currentValue.strVal;
            int64 re = 0;
            stream >> re;
            return re;
    }
        break;

    case Undefined:
        return 0;
        break;
    }
    }

    return 0;
}

long long Variant::toLongLong() const
{
    return this->toInt64();
}

const char * Variant::toCharArray() const
{
    //Try to return the variant as a char array

    switch(this->currentType)
    {
    case Int:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.iVal;//Assign the stream to the integer value
        const char * re;//Create the return char array
        re  = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Float:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.fVal;//Assign the stream to the floating point value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Double:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.dVal;//Assign the stream to the double value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case ULong:
    {
        std::stringstream stream;//Create the stream where the ineger will be stored
        stream << this->currentValue.ulVal;//Assign the stream to the unsigned long value
        const char * re;//Create the return char array
        re = stream.str().c_str();//Assign the char array with the value of the stream
        return (char*) re;//Return the char array
    }
        break;

    case Int64:
    {
        std::stringstream stream;
        stream << this->currentValue.i64Val;
        const char * re;
        re = stream.str().c_str();
        return (char*)re;
    }

    case Bool:
    {
        if(this->currentValue.bVal == true)
            return (char*)"1";//Return one for true
        return (char*)"0";//Return zero for false
    }
        break;

    case  Char:
    {
        std::stringstream stream;//Create the stream to hold the char
        stream << this->currentValue.cVal;//Set the stream to the char
        return (char*)stream.str().c_str();//Return the stream as a char array
    }
        break;

    case CharArray:
        return (char*)this->currentValue.strVal;//Just return the char array
        break;

    case Undefined:
        return (char*)NULL;//Return nothing as for failed

    }


    return (char*)NULL;//Return nothing as for failed
}

bool Variant::isTrue(const Variant &Var)
{
    //Check if the passed variant is true or false
    const char * str = (const char*)Var.toCharArray();//Convert the variant to a cstring
    int strsize = strlen((const char*)str);//Get the lenght of the string

    int TCount = 0;//Too keep track of the number of true chars in the string
    int FCount = 0;//Too keep track of the number of false chars in the string

    for(int i = 0; i < strsize;++i)
    {
        //Loop through the entire string
        //And check each char if it is true or not
        if(str[i] == '0')
            ++FCount;//A new false char was found,increase the number of false chars
        else
            ++TCount;//Else it is a true char increase the number of true chars in the string
    }

    if(TCount > FCount)
        return true;//The string contained more true chars than false chars
    else if(FCount > TCount)
        return false;//The string contained more false chars than true chars

        //If it has gotten to this point TCount and FCount is the same value
        //then base boolean of the first char in the string
        if(str[0] == '0')
            return false;//The first char is false so then return false
        return true;//Else the first char is true so return true
}

char Variant::toChar() const
{
    //Try to convert the current Variant to a char
    switch(this->currentType)
    {
    case Int:
    {
        std::stringstream stream;//Create the stringstream that will hold tje integer value
        stream << this->currentValue.iVal;//Assign the stream to the integer value
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char

    }
        break;

    case Float:
    {
        std::stringstream stream;//Create the stringstream that will hold the float valie
        stream << this->currentValue.fVal;//Assign the stream to the float value
        char Re = '0';//Create the return char
        stream >> Re;///Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case Double:
    {
        std::stringstream stream;//Create the stringstream that will hold the double
        stream << this->currentValue.dVal;//Assign the stream to the double
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case ULong:
    {
        std::stringstream stream;//Create the stringstream that will hold the double
        stream << this->currentValue.ulVal;//Assign the stream to the unsigned long value
        char Re = '0';//Create the return char
        stream >> Re;//Assign the char to the value of the stream
        return Re;//Return the char
    }
        break;

    case Int64:
    {
        std::stringstream stream;
        stream << this->currentValue.i64Val;
        char Re = '0';
        stream >> Re;
        return Re;
    }
        break;
    case Bool:
    {
        if(this->currentValue.bVal == true)
            return (char)'1';//Return true
        return (char)'0';//Return false
    }
        break;

    case Char:
        return this->currentValue.cVal;//Just return the char value
        break;
    case CharArray:
    {
        if(strlen((const char*)this->currentValue.strVal) > 0)
            return (char)this->currentValue.strVal[0];//Return the first char of the string
        else
        {
            return (char)'0';
        }

    }
        break;

    case Undefined:
    {
        return '0';//Return 0 for failed
    }
    }

    return (char)'0';//Return 0 for failed

}



int Variant::toInt(const Variant &val)
{
    return val.toInt();
}

float Variant::toFloat(const Variant &val)
{
    return val.toFloat();
}

double Variant::toDouble(const Variant &val)
{
    return val.toDouble();
}

unsigned long Variant::toULong(const Variant &val)
{
    return val.toULong();
}

int64 Variant::toInt64(const Variant &val)
{
    return val.toInt64();
}

long long Variant::toLongLong(const Variant &val)
{
    return val.toInt64();
}


bool Variant::toBool(const Variant &val)
{
    return val.toBool();
}

char Variant::toChar(const Variant &val)
{
    return val.toChar();
}

const char * Variant::toCharArray(const Variant &val) 
{
    return val.toCharArray();
}

void Variant::clear()
{
    //Clear all the Variants values
    currentValue.iVal = 0;//Set the integer value to zero
    currentValue.fVal = 0;//Set the float value to zero
    currentValue.dVal = 0;//Set the double value to zero
    currentValue.cVal = (char)(int)0;//Set the char value to null
    currentValue.ulVal = 0;
    currentValue.i64Val = 0;
    currentValue.strVal = (char*)NULL;//Set the string value to empty
    currentValue.bVal = false;//Set the boolean value to false
    setCurrentType(Undefined);//Set the current type to undefined
    //no type has been set by the user yet
}

bool Variant::canCastTo(const Variant::Types type) const
{
    //Check if the current variant can be casted
    //to another type
    if(this->currentType == Char || this->currentType == Int
            || this->currentType == Float || this->currentType == Double || this->currentType == Bool || this->currentType == ULong || this->currentType == Int64)
    {
        //If the current Variant is any of these types
        return (type == Char || type == Int || type == Float || type == Double || type == Bool || type == ULong || type == Int64);

    }

    //The remaning type is the char array which can't be casted with anything
    return false;//therefore return false for not can be casted with the type the user passed
}

bool Variant::cast(int val)
{

    switch(this->currentType)
    {
    case Int:
        val = (int)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (int)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (int)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (int)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (int)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(int64 val)
{
    //Cast the current variant to a 64 bit integer
    switch(this->currentType)
    {
    case Int:
        val = (int64)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (int64)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (int64)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (int64)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = this->currentValue.i64Val;
        return true;
        break;
    case Char:
        val = (int64)this->currentValue.cVal;
        return true;
        break;
    case Bool:
        val = (int64)this->currentValue.bVal;
        return true;
        break;
    case CharArray:
        return false;
        break;
    case Undefined:
        return false;
        break;
    }

    return false;
}

bool Variant::cast(unsigned long val)
{

    switch(this->currentType)
    {
    case Int:
        val = (unsigned long)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (unsigned long)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (unsigned long)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (unsigned long)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (unsigned long)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (unsigned long)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (unsigned long)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;

    case Undefined:
        return false;
        break;
    }

    return false;
}

bool Variant::cast(float val)
{

    switch(this->currentType)
    {
    case Int:
        val = (float)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (float)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (float)this->currentValue.dVal;
        return true;
        break;

    case ULong:
        val = (float)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (float)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (float)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (float)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(double val)
{
    switch(this->currentType)
    {
    case Int:
        val = (double)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (double)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (double)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (double)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (double)this->currentValue.i64Val;
        return true;
        break;

    case Bool:
        val = (double)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (double)this->currentValue.cVal;
        return true;
        break;
    case CharArray:
        return false;
        break;
    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::cast(char val)
{

    switch(this->currentType)
    {
    case Int:
        val = (char)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (char)(int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (char)(int)this->currentValue.dVal;
        return true;
        break;
    case ULong:
        val = (char)(int)this->currentValue.ulVal;
        return true;
        break;
    case Int64:
        val = (char)(int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (char)(int)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (char)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;

    case Undefined:
        return false;
        break;
    }
    return false;
}


bool Variant::cast(bool val)
{
    switch(this->currentType)
    {
    case Int:
        val = (bool)this->currentValue.iVal;
        return true;
        break;
    case Float:
        val = (bool)(int)this->currentValue.fVal;
        return true;
        break;
    case Double:
        val = (bool)(int)this->currentValue.dVal;
        return true;
        break;

    case ULong:
        val = (bool)(int)this->currentValue.ulVal;
        return true;
        break;

    case Int64:
        val = (bool)(int)this->currentValue.i64Val;
        return true;
        break;
    case Bool:
        val = (bool)this->currentValue.bVal;
        return true;
        break;
    case Char:
        val = (bool)this->currentValue.cVal;
        return true;
        break;

    case CharArray:
        return false;
        break;

    case Undefined:
        return false;
        break;
    }
    return false;
}

bool Variant::setValue(const Variant &val, const Types T)
{
    //Set the Variant value without changing the T

    setCurrentType(T);
    if(currentType == T)
    {//If the current type actually was set
    switch(T)
    {
    case Int:
        this->currentValue.iVal = val.toInt();
        return true;
        break;
    case Float:
        this->currentValue.fVal = val.toFloat();
        return true;
        break;
    case Double:
        this->currentValue.dVal = val.toDouble();
        return true;
        break;
    case ULong:
        this->currentValue.ulVal = val.toULong();
        return true;
        break;       
    case Int64:
        this->currentValue.i64Val = val.toInt64();
        return true;
        break;
    case Bool:
        this->currentValue.bVal = val.toBool();
        return true;
        break;
    case Char:
        this->currentValue.cVal = val.toChar();
        return true;
        break;
    case CharArray:
        this->currentValue.strVal = _strdup(val.toCharArray());
        return true;
        break;

    default:
        return false;
        break;
    }
    }

    return false;//Return false for failed
}

bool Variant::operator ==(const Variant &val) const
{
return matchingValues(val);//Check if the values and the types are the same
}

bool Variant::matchingTypes(const Variant &val) const
{
    return (this->currentType ==  val.currentType);
}

bool Variant::matchingValues(const Variant &val) const
{
    if(matchingTypes(val))
    {
        //The types must be the same for the value to match
        switch(this->currentType)
        {
        case Int:
        {
            return (this->currentValue.iVal == val.currentValue.iVal);

        }
            break;

        case Float:
        {
            return (this->currentValue.fVal == val.currentValue.fVal);

        }
            break;

        case Double:
        {
            return (this->currentValue.dVal == val.currentValue.dVal);
        }
            break;

        case ULong:
        {
            return (this->currentValue.ulVal == val.currentValue.ulVal);
        }
            break;

        case Int64:
        {
            return (this->currentValue.i64Val == val.currentValue.i64Val);
        }
            break;

        case Bool:
        {
            return (this->currentValue.bVal == val.currentValue.bVal);
        }
            break;

        case Char:
        {
            return (this->currentValue.cVal == val.currentValue.cVal);
        }
            break;

        case CharArray:
        {
            return strcmp(this->currentValue.strVal,val.currentValue.strVal) == 0;
        }
            break;

        case Undefined:
            return true;//Both the variants are undefined
            break;

    }

    }

    return false;
}

bool Variant::operator !=(const Variant &val) const
{
    //Check if the current variant and the passed variant
    //don't have the same value and or type
    return (!matchingValues(val));
}


bool Variant::isUndefined() const
{
    return (currentType == Undefined);
}


bool Variant::isIntegerData() const
{
    if(currentType == Int || currentType == ULong || currentType == Int64)
        return true;

    return false;//The integer only contains data that can be converted to a integer
}

bool Variant::isDecimalData() const
{
    if(currentType == Float || currentType == Double)
        return true;
    return false;
}
Posts 1–10 of 10 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us