diff --git a/src/IDs.cpp b/src/IDs.cpp index a52efa7..f7ab02a 100644 --- a/src/IDs.cpp +++ b/src/IDs.cpp @@ -35,10 +35,12 @@ #include"command.h" #include"ExpandingArray.h" -class IDs { +class IDs : public Singleton { public: std::vector flags; - SINGLETON(IDs); +private: + IDs(); + friend Singleton; }; IDs::IDs(){ @@ -49,7 +51,7 @@ IDs::IDs(){ fclose(pFile); } -class TextIDs{ +class TextIDs : public Singleton { public: uint idClasses[0x20]; bool CheckID(uint,uint); @@ -57,8 +59,9 @@ class TextIDs{ bool IsDefined(uint); static void Clear(); std::vector specials; - SINGLETON(TextIDs); private: + TextIDs(); + friend Singleton; static Expanding0Array _m; }; Expanding0Array TextIDs::_m; diff --git a/src/act0.cpp b/src/act0.cpp index 577359e..1111e30 100644 --- a/src/act0.cpp +++ b/src/act0.cpp @@ -209,9 +209,10 @@ int PropData::CountFE(){ return ret; } -class Prop08Tracking{ - STATIC(Prop08Tracking) +class Prop08Tracking { public: + Prop08Tracking() = delete; + static void Set(uint feat,uint id){ _m[feat][id]=true; } diff --git a/src/act123.h b/src/act123.h index 653ffe6..00f2827 100644 --- a/src/act123.h +++ b/src/act123.h @@ -25,7 +25,7 @@ class PseudoSprite; -struct act123{ +struct act123 : Singleton { void init(); uint MaxFoundFeat()const; @@ -62,10 +62,12 @@ struct act123{ }defined2IDs; uint act3feature,act3spritenum; - SINGLETON(act123) +private: + act123(); + friend Singleton; }; -class Check2v{ +class Check2v : public Singleton { struct VarData{ VarData():width(0){} VarData(int x):width(x){} @@ -84,8 +86,9 @@ class Check2v{ static uint Prohibit0Mask(uint); static uint GetEffFeature(uint,uint); bool IsValid(uint feature, uint var)const; - SINGLETON(Check2v) private: + Check2v(); + friend Singleton; ExpandingArrayglobvars; std::vector data; uint maxop; @@ -115,15 +118,16 @@ class varRange{ void AddRangeInternal(uint min,uint max,RenumMessageId unreachable); }; -class rand2{ +class rand2 : public Singleton { private: + rand2(); + friend Singleton; struct rand2info{ uint bits[2],numtriggers; }; std::vector data; public: void CheckRand(uint feat,uint type,uint triggers,uint first,uint nrand); - SINGLETON(rand2); }; //An object of this class will check and define the given ID when it is destroyed. @@ -138,9 +142,11 @@ class Define2{ bool checks1C; }; -class Callbacks { +class Callbacks : public Singleton { public: std::vector flags; - SINGLETON(Callbacks); +private: + Callbacks(); + friend Singleton; }; diff --git a/src/act5.cpp b/src/act5.cpp index e4dca9d..fcf3b1a 100644 --- a/src/act5.cpp +++ b/src/act5.cpp @@ -37,13 +37,14 @@ extern bool _base_grf; -class c5{ +class c5 : public Singleton { public: int maxFeature(){return (int)sizes.size()+3;} const std::vector&operator[](int x)const {return sizes[x-4];} - SINGLETON(c5) private: std::vector >sizes; + c5(); + friend Singleton; }; c5::c5(){ diff --git a/src/act79D.cpp b/src/act79D.cpp index 3f3245a..a010a26 100644 --- a/src/act79D.cpp +++ b/src/act79D.cpp @@ -33,7 +33,7 @@ #include"pseudo.h" #include"command.h" -class Vars{ +class Vars : public Singleton { public: bool canRead7(uint v) const { return (v < 0x80 || (v < numvars && data.at(v & 0x7F) & 0x80)); } bool canReadD(uint v) const { return (v < 0x80 || v == 0xFF || (v < numvars && data.at(v & 0x7F) & 0x40)); } @@ -45,14 +45,18 @@ class Vars{ } std::vector data; uint numvars; - SINGLETON(Vars) +private: + Vars(); + friend Singleton; }; -class D { +class D : public Singleton { public: std::vector flags; uint maxpatchvar,maxop; - SINGLETON(D) +private: + D(); + friend Singleton; }; Vars::Vars(){ diff --git a/src/actB.cpp b/src/actB.cpp index 714adfe..4cc8f00 100644 --- a/src/actB.cpp +++ b/src/actB.cpp @@ -32,11 +32,13 @@ #include"pseudo.h" #include"command.h" -class B{ +class B : public Singleton { public: uint maxSeverity; std::vector data; - SINGLETON(B); +private: + B(); + friend Singleton; }; B::B(){ diff --git a/src/language_mgr.h b/src/language_mgr.h index 3692e30..6310511 100644 --- a/src/language_mgr.h +++ b/src/language_mgr.h @@ -56,8 +56,7 @@ typedef std::map str2lang_map; /*! Handles program language detection and selection. */ -class LanguageMgr { - SINGLETON(LanguageMgr); +class LanguageMgr : public Singleton { public: /*! Gets the current language ID. \return ID of the current language. @@ -80,11 +79,14 @@ class LanguageMgr { RenumLanguageId DecodeLanguageCode(const std::string& code) const; private: + LanguageMgr(); + friend Singleton; + /*! Initializes the language map with data about supported languages. */ void InitLanguageMap(); - RenumLanguageId currentId; /*!< Current language ID */ - str2lang_map codeIdMap; /*!< Maps language codes to identifiers */ + RenumLanguageId currentId{}; /*!< Current language ID */ + str2lang_map codeIdMap{}; /*!< Maps language codes to identifiers */ }; #endif // _RENUM_LANGUAGE_MGR_H_INCLUDED_ diff --git a/src/message_mgr.h b/src/message_mgr.h index d983160..2ac9f84 100644 --- a/src/message_mgr.h +++ b/src/message_mgr.h @@ -116,8 +116,7 @@ typedef std::map msgid2data_map; typedef std::map extid2data_map; /*! Manages program messages and extra texts for various supported languages. */ -class MessageMgr { - SINGLETON(MessageMgr); +class MessageMgr : public Singleton { public: const static MessageData UNKNOWN_MESSAGE; /*!< Fallback message data. */ const static std::string UNDEFINED_TEXT; /*!< Fallback message text. */ @@ -160,6 +159,9 @@ class MessageMgr { void SetExtraText(RenumExtraTextId i, RenumLanguageId lang, const std::string& text); private: + MessageMgr(); + friend Singleton; + /*! Initialize message data and properties. */ void InitMessages(); diff --git a/src/sanity.cpp b/src/sanity.cpp index e2e5475..745087b 100644 --- a/src/sanity.cpp +++ b/src/sanity.cpp @@ -40,14 +40,16 @@ bool _base_grf = false; -class features{ +class features : public Singleton { public: struct featdat{ uchar validbits; uchar act2type; }; std::vector data; - SINGLETON(features) +private: + features(); + friend Singleton; }; features::features(){ diff --git a/src/singleton.h b/src/singleton.h index af452f3..156774a 100644 --- a/src/singleton.h +++ b/src/singleton.h @@ -23,30 +23,58 @@ #ifndef _RENUM_SINGLETON_H_INCLUDED_ #define _RENUM_SINGLETON_H_INCLUDED_ -//Mutable singleton -#define SINGLETON(class)\ -public:\ - static class&Instance(){static class obj;return obj;}\ - static const class&CInstance(){return Instance();}\ -private:\ - class();\ - class(const class&);\ - void operator=(const class&); - -//Immutable singleton -#define C_SINGLETON(class)\ -public:\ - static const class&Instance(){static const class obj;return obj;}\ -private:\ - class();\ - class(const class&);\ - void operator=(const class&); - -//Non-object class -#define STATIC(class)\ -private:\ - class();\ - class(const class&);\ - void operator=(const class&); +/** + * Base class to make a singleton class. + * @tparam T the singleton class. + */ +template +class Singleton { +public: + /** + * Get the singleton class instance. + * @return the singleton class instance. + */ + static T &Instance() { + static T instance{}; + return instance; + } + + /** + * Get the const singleton class instance. + * @return the const singleton class instance. + */ + static const T &CInstance() { return Instance(); } + + Singleton(const Singleton &) = delete; + Singleton &operator=(const Singleton) = delete; + +protected: + Singleton() = default; + virtual ~Singleton() = default; +}; + +/** + * Base class to make a const singleton class. + * @tparam T the singleton class. + */ +template +class ConstSingleton { +public: + /** + * Get the const singleton class instance. + * @return the const singleton class instance. + */ + static const T &Instance() { + static T instance; + return instance; + } + + ConstSingleton(const ConstSingleton &) = delete; + ConstSingleton &operator=(const ConstSingleton) = delete; + +protected: + ConstSingleton() = default; + virtual ~ConstSingleton() = default; +}; #endif // _RENUM_SINGLETON_H_INCLUDED_ diff --git a/src/strings.cpp b/src/strings.cpp index 344c72d..05351ef 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -36,12 +36,14 @@ #include"messages.h" #include"command.h" -class check4{ +class check4 : public Singleton { public: int GetGenericPerms(int feature); int GetNamePerms(int feature); - SINGLETON(check4) std::vector features; +private: + check4(); + friend Singleton; }; check4::check4(){ @@ -412,9 +414,11 @@ std::string MakeStack(int items,...){ * Lang ID code *******************************************************/ -struct langNames{ +struct langNames : ConstSingleton { std::string names[0x80]; - C_SINGLETON(langNames) +private: + langNames(); + friend ConstSingleton; }; langNames::langNames(){