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 gyk@yamido.com



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.