This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Singleton Class with Order Of Destruction Submitted by

This singleton class is implemented using template type list class to order the singleton's destruction's order. this is how you can use it:

    #include "singleton.h"

    class SingletonB;

    // this singleton must be destroyed before SingletonB's instance
    class SingletonA
    {
    DECLARE_SINGLETON_DEPENDENTS(SingletonA, BUILD_TYPE_LIST_1(SingletonB))
    SingletonA () {}
    ~SingletonB () {}
    };

    // this singleton has no dependents
    class SingletonB
    {
    DECLARE_SINGLETON_DEPENDENTS(SingletonB, end_of_type_list)
    SingletonB () {}
    ~SingletonB () {}
    };

    int main ()
    {
        SingletonA &a = GET_SINGLETON(SingletonA);
        SingletonB &b = GET_SINGLETON(SingletonB);
        return 0;
    }

If you have any idea about it, please contact me :)

Currently browsing [singleton_using_typelist.zip] (5,362 bytes) - [singleton.h] - (2,997 bytes)

    /* using type list to order the singletons' destruction */
    #ifndef __SINGLETON__
    #define __SINGLETON__
    #include "typelist.h"
    #include <cstddef>
    #include <vector>
    #ifndef _MSC_VER
    using std::size_t;
    #endif
    using std::vector;
    typedef void (*__destroy_func__) ();
    template <typename _Type> class Singleton;

    template <typename _TypeList>
    struct _type_list_destructor_register
    {
    	static inline void Travel (__destroy_func__ df)
    	{
    		typedef _TypeList::this_type this_type;
    		typedef _TypeList::this_list this_list;
    		Singleton<this_type>::instance_manager::get().register_destructor(df);
    		_type_list_destructor_register<this_list>::Travel (df);
    	}
    };

    template <>
    struct _type_list_destructor_register <end_of_type_list>
    { static inline void Travel (__destroy_func__) {} };

    template <typename _Type>
    class Singleton
    {
    public:
    	typedef _Type type;
    	typedef typename _Type::destroy_dependents dependents;
    	typedef Singleton<_Type> singleton;

    	class instance_manager;
    	friend instance_manager;

    	class instance_manager
    	{
    		friend singleton;

    	public:
    		struct _creator
    		{
    			_creator () { instance_manager::get(); }
    			void nop () const {}
    		};
    		static _creator creator;

    	public:
    		~instance_manager () { destroy_instance (); }
    		void register_destructor (__destroy_func__ destructor)
    		{ _M_managed.push_back(destructor); }
    		bool check_instance () { return _M_instance ? true : false; }
    		type *instance ()
    		{
    			return _M_instance ?
    			_M_instance :
    			_M_instance = singleton::_create_instance();
    		}

    		void destroy_instance ()
    		{
    			for (size_t i=0; i<_M_managed.size(); i++)
    				(*_M_managed[i])();
    			singleton::_destroy_instance (_M_instance);
    			_M_instance = 0;
    		}

    		static instance_manager &get ()
    		{
    			static instance_manager im;
    			creator.nop ();
    			return im;
    		}

    		static inline void destroy ()
    		{ singleton::instance_manager::get().destroy_instance(); }

    	private:
    		instance_manager () : _M_instance(0)
    		{ _type_list_destructor_register<dependents>::Travel(destroy); }
    		type *_M_instance;
    		vector<__destroy_func__> _M_managed;
    	};

    	static inline type & instance ()
    	{ return *instance_manager::get().instance(); }

    private:
    	static inline type *_create_instance () { return new type; }
    	static inline void _destroy_instance (type *p) { delete p; }
    };

    #define DECLARE_SINGLETON_DEPENDENTS(type,typelist) \
    typedef typelist destroy_dependents; \
    friend Singleton< type >;

    #define DECLARE_SINGLETON_NO_DEPENDENTS(type) \
    typedef end_of_type_list destroy_dependents; \
    friend Singleton< type >;

    #define IMPLEMENT_SINGLETON(type) \
    Singleton< type >::instance_manager::\
    _creator Singleton< type >::instance_manager::creator;

    #define GET_SINGLETON( type ) \
    (Singleton< type >::instance())

    template <typename _Type>
    typename Singleton<_Type>::instance_manager::_creator
    Singleton<_Type>::instance_manager::creator;

    #endif//__SINGLETON__

Currently browsing [singleton_using_typelist.zip] (5,362 bytes) - [singleton_test.cpp] - (697 bytes)

    // singleton_test.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "singleton.h"
    class SingletonClassB;
    class SingletonClassA
    {
    DECLARE_SINGLETON_DEPENDENTS(SingletonClassA, BUILD_TYPE_LIST_1(SingletonClassB))
    SingletonClassA() {}
    ~SingletonClassA() {}
    };

    class SingletonClassB
    {
    DECLARE_SINGLETON_DEPENDENTS(SingletonClassB, end_of_type_list)
    SingletonClassB() {}
    ~SingletonClassB() {}
    };

    IMPLEMENT_SINGLETON(SingletonClassA)
    IMPLEMENT_SINGLETON(SingletonClassB)

    int main(int argc, char* argv[])
    {
    	SingletonClassA *a = &GET_SINGLETON(SingletonClassA);
    	SingletonClassB *b = &GET_SINGLETON(SingletonClassB);
    	return 0;
    }

Currently browsing [singleton_using_typelist.zip] (5,362 bytes) - [StdAfx.cpp] - (301 bytes)

    // stdafx.cpp : source file that includes just the standard includes
    //	singleton_test.pch will be the pre-compiled header
    //	stdafx.obj will contain the pre-compiled type information

    #include "stdafx.h"

    // TODO: reference any additional headers you need in STDAFX.H
    // and not in this file

Currently browsing [singleton_using_typelist.zip] (5,362 bytes) - [StdAfx.h] - (667 bytes)

    // stdafx.h : include file for standard system include files,
    //  or project specific include files that are used frequently, but
    //      are changed infrequently
    //

    #if !defined(AFX_STDAFX_H__64B814F1_9896_4104_BD1A_5551A966282E__INCLUDED_)
    #define AFX_STDAFX_H__64B814F1_9896_4104_BD1A_5551A966282E__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    // TODO: reference additional headers your program requires here

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_STDAFX_H__64B814F1_9896_4104_BD1A_5551A966282E__INCLUDED_)

Currently browsing [singleton_using_typelist.zip] (5,362 bytes) - [typelist.h] - (1,565 bytes)

    #ifndef __TYPELIST__
    #define __TYPELIST__
    struct end_of_type_list {};
    template <typename _Type, typename _List>

    struct TypeList
    {
    	typedef _Type this_type;
    	typedef _List this_list;
    };

    #define BUILD_TYPE_LIST_1(type1) \
    TypeList<type1, end_of_type_list>

    #define BUILD_TYPE_LIST_2(type1, type2) \
    TypeList<type1, BUILD_TYPE_LIST_1(type2) >

    #define BUILD_TYPE_LIST_3(type1, type2, type3) \
    TypeList<type1, BUILD_TYPE_LIST_2(type2,type3) >

    #define BUILD_TYPE_LIST_4(type1, type2, type3, type4) \
    TypeList<type1, BUILD_TYPE_LIST_3(type2,type3,type4) >

    #define BUILD_TYPE_LIST_5(type1, type2, type3, type4, type5) \
    TypeList<type1, BUILD_TYPE_LIST_4(type2,type3,type4,type5) >

    #define BUILD_TYPE_LIST_6(type1, type2, type3, type4, type5, type6) \
    TypeList<type1, BUILD_TYPE_LIST_5(type2,type3,type4,type5,type6) >

    #define BUILD_TYPE_LIST_7(type1, type2, type3, type4, type5, type6, type7) \
    TypeList<type1, BUILD_TYPE_LIST_6(type2,type3,type4,type5,type6,type7) >

    #define BUILD_TYPE_LIST_8(type1, type2, type3, type4, type5, type6, type7, type8) \
    TypeList<type1, BUILD_TYPE_LIST_7(type2,type3,type4,type5,type6,type7,type8) >

    #define BUILD_TYPE_LIST_9(type1, type2, type3, type4, type5, type6, type7, type8, type9) \
    TypeList<type1, BUILD_TYPE_LIST_8(type2,type3,type4,type5,type6,type7,type8,type9) >

    #define BUILD_TYPE_LIST_10(type1, type2, type3, type4, type5, type6, type7, type8, type9, type10) \
    TypeList<type1, BUILD_TYPE_LIST_9(type2,type3,type4,type5,type6,type7,type8,type9,type10) >

    #endif//__TYPELIST__

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.