Show Index FrameGo Up
Hosted at Get Eagle Mode at SourceForge.net. Fast, secure and Free Open Source software downloads
//------------------------------------------------------------------------------
// emAnything.h
//
// Copyright (C) 2015-2016 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// 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 version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emAnything_h
#define emAnything_h

#ifndef emStd1_h
#include <emCore/emStd1.h>
#endif


//==============================================================================
//================================= emAnything =================================
//==============================================================================

class emAnything {

public:

        // Class for holding any type of value. Copies are implicitly shared.
        // The derived template class emCastAnything is used to cast to and from
        // emAnything. Examples:
        //
        //   // Convert an integer to emAnything:
        //   emAnything a = emCastAnything<int>(100);
        //
        //   // Get back that integer:
        //   const int * pi = emCastAnything<int>(a);
        //   if (pi) {
        //     int i = *pi;
        //     printf("a = %d\n", i);
        //   }
        //   else {
        //     printf("Error: a is not an int.\n");
        //   }
        //
        //   // Convert an emString to emAnything:
        //   emAnything a2 = emCastAnything<emString>(emString("Hello"));
        //
        //   // Get back that string:
        //   const emString * ps = emCastAnything<emString>(a2);
        //   if (ps) {
        //     printf("a2 = %s\n", ps->Get());
        //   }
        //   else {
        //     printf("Error: a2 is not an emString.\n");
        //   }

        emAnything();
                // Construct invalid.

        emAnything(const emAnything & anything);
                // Construct a copy.

        ~emAnything();
                // Destruct.

        emAnything & operator = (const emAnything & anything);
                // Copy.

protected:

        struct AbstractSharedData {
                AbstractSharedData();
                virtual ~AbstractSharedData();
                unsigned int RefCount;
        };

        emAnything(AbstractSharedData * data);

        AbstractSharedData * Data;
};


//==============================================================================
//=============================== emCastAnything ===============================
//==============================================================================

template <class VALUE> class emCastAnything : public emAnything {

public:

        // Helper class for casting emAnything to and from any type.
        // Please see the examples in the description of emAnything.

        emCastAnything(const VALUE & value);
        emCastAnything(const emAnything & anything);

        operator const VALUE * () const;

private:

        struct SharedData : AbstractSharedData {
                SharedData(const VALUE & value);
                virtual ~SharedData();
                VALUE Value;
        };
};


//==============================================================================
//============================== Implementations ===============================
//==============================================================================

inline emAnything::emAnything()
        : Data(NULL)
{
}

inline emAnything::AbstractSharedData::AbstractSharedData()
        : RefCount(1)
{
}

inline emAnything::emAnything(AbstractSharedData * data)
        : Data(data)
{
}

template <class VALUE> inline emCastAnything<VALUE>::emCastAnything(
        const VALUE & value
) : emAnything(new SharedData(value))
{
}

template <class VALUE> inline emCastAnything<VALUE>::emCastAnything(
        const emAnything & anything
) : emAnything(anything)
{
}

template <class VALUE> inline emCastAnything<VALUE>::SharedData::SharedData(
        const VALUE & value
) : Value(value)
{
}

template <class VALUE> emCastAnything<VALUE>::operator const VALUE * () const
{
        if (Data) {
                const SharedData * d=
                        dynamic_cast<const typename emCastAnything<VALUE>::SharedData*>(Data)
                ;
                if (d) return &d->Value;
        }
        return NULL;
}

template <class VALUE> emCastAnything<VALUE>::SharedData::~SharedData()
{
}


#endif