
Hi, I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class. However after looking at the implementation I saw there was no private default copy constructor or assignment operator. Does this not mean that I could create multiple instances of my singleton via assignment or some other form of copying? I saw some discussion of a better singleton representation in boost and I was wondering what the status of this was, and I was also wondering what other people use for their singletons? Thanks Tom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This message is intended only for the personal and confidential use of the designated recipient(s) named above. If you are not the intended recipient of this message you are hereby notified that any review, dissemination, distribution or copying of this message is strictly prohibited. This communication is for information purposes only and should not be regarded as an offer to sell or as a solicitation of an offer to buy any financial product, an official confirmation of any transaction, or as an official statement of Lehman Brothers. Email transmission cannot be guaranteed to be secure or error-free. Therefore, we do not represent that this information is complete or accurate and it should not be relied upon as such. All information is subject to change without notice.

We use Loki::Singleton (full policy based implementation of the singleton pattern). http://sourceforge.net/projects/loki-lib/ Marius -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Medland, Thomas M Sent: Tuesday, May 08, 2007 1:09 PM To: boost@lists.boost.org Subject: [boost] Boost singleton Hi, I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class. However after looking at the implementation I saw there was no private default copy constructor or assignment operator. Does this not mean that I could create multiple instances of my singleton via assignment or some other form of copying? I saw some discussion of a better singleton representation in boost and I was wondering what the status of this was, and I was also wondering what other people use for their singletons? Thanks Tom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This message is intended only for the personal and confidential use of the designated recipient(s) named above. If you are not the intended recipient of this message you are hereby notified that any review, dissemination, distribution or copying of this message is strictly prohibited. This communication is for information purposes only and should not be regarded as an offer to sell or as a solicitation of an offer to buy any financial product, an official confirmation of any transaction, or as an official statement of Lehman Brothers. Email transmission cannot be guaranteed to be secure or error-free. Therefore, we do not represent that this information is complete or accurate and it should not be relied upon as such. All information is subject to change without notice. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ********************************************************************** This communication and all information (including, but not limited to, market prices/levels and data) contained therein (the "Information") is for informational purposes only, is confidential, may be legally privileged and is the intellectual property of ICAP plc and its affiliates ("ICAP") or third parties. No confidentiality or privilege is waived or lost by any mistransmission. The Information is not, and should not be construed as, an offer, bid or solicitation in relation to any financial instrument or as an official confirmation of any transaction. The Information is not warranted, including, but not limited, as to completeness, timeliness or accuracy and is subject to change without notice. ICAP assumes no liability for use or misuse of the Information. All representations and warranties are expressly disclaimed. The Information does not necessarily reflect the views of ICAP. Access to the Information by anyone else other than the recipient is unauthorized and any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it is prohibited. If you receive this message in error, please immediately delete it and all copies of it from your system, destroy any hard copies of it and notify the sender. **********************************************************************

Medland, Thomas M wrote:
I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class.
The only singleton I know in boost is the one in the implementation details of pool. Is that what you're talking about?

On 5/8/07, Medland, Thomas M <thomas.medland@lehman.com> wrote:
Hi,
I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class. However after looking at the implementation I saw there was no private default copy constructor or assignment operator. Does this not mean that I could create multiple instances of my singleton via assignment or some other form of copying? I saw some discussion of a better singleton representation in boost and I was wondering what the status of this was, and I was also wondering what other people use for their singletons?
Thanks Tom
Well, I use the following. It's pretty simple and it works. #ifndef STE_PATTERN_SINGLETON_HPP #define STE_PATTERN_SINGLETON_HPP #include <memory> #include <boost/noncopyable.hpp> #include <boost/thread/mutex.hpp> namespace ste { namespace pattern { //+--------------------------------------------------------------------------------------+ //| instantiation policies, etc. class static_instantiation { template <typename T> class holder { friend class static_instantiation; static T instance_s; }; protected: template <typename T> static void make(T*& p) { p = &holder<T>::instance_s; } }; template <typename T> T static_instantiation::holder<T>::instance_s; class local_static_instantiation { protected: template <typename T> static void make(T*& p) { static T instance; p = &instance; } }; //| basically auto_ptr<T>, which is too common to be made a friend of T for the purpose. template <typename T> class singleton_destroyer : private boost::noncopyable { friend class lazy_instantiation; explicit singleton_destroyer(T* p) : p_(p) {} ~singleton_destroyer() { try { if (p_) delete p_, p_=0; } catch (...) {} } T* p_; }; class lazy_instantiation { protected: template <typename T> static void make(T*& p) { static singleton_destroyer<T> sd(p = new T()); } }; //+--------------------------------------------------------------------------------------+ //| rules of application: //| first, declare/make both the default (and only) ctor and the dtor of your singleton //| class T protected. //| second, make both the chosen instantiation policy (and singleton_destroyer<T> if //| lazy_instantiation is chosen) friend(s) of T. //| third, applying the Coplien::Curiously Recurring Template pattern, //| define T as in one of the following examples (other combinations possible, too). //| //| one that is most common (multi-threaded): //| class T : public singleton<T> {...}; //| //| one that uses static storage (multi-threaded): //| class T : public singleton<T, static_instantiation> {...}; //| //| one that uses local static storage (single-threaded, Meyers-like): //| class T : singleton<T, local_static_instantiation, ZThread::NotLocked> {...}; template <typename T, typename I/*instantiation policy*/=lazy_instantiation, typename L/*lock type*/=boost::mutex> class singleton : private I, private boost::noncopyable { public: static T* instance(); protected: singleton() {} //neither direct instantiation/usage of singleton<T> virtual ~singleton() = 0; //nor accidental/sneak destruction }; template <typename T, typename I, typename L> T* singleton<T,I,L>::instance() { static T* p = 0; if (!p) { //Schmidt::Double-Checked Locking, ensuring thread safety static L lock; //uses local static storage to avoid static member construction boost::mutex::scoped_lock<L> g(lock); if (!p) I::make(p); } return p; }; template <typename T, typename I, typename L> singleton<T,I,L>::~singleton() { } } //namespace ste::pattern } //namespace ste #endif //STE_PATTERN_SINGLETON_HPP -- Greg

Gregory Dai ha escrito:
On 5/8/07, Medland, Thomas M <thomas.medland@lehman.com> wrote:
Hi,
I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class. However after looking at the implementation I saw there was no private default copy constructor or assignment operator. Does this not mean that I could create multiple instances of my singleton via assignment or some other form of copying? I saw some discussion of a better singleton representation in boost and I was wondering what the status of this was, and I was also wondering what other people use for their singletons?
Thanks Tom
Well, I use the following. It's pretty simple and it works.
[...] Hello Greg, I think there's a potential problem with your static_instantiation policy (or at least a limitation in applicability) due to its relying on the class template static member static_instantiation::holder<T>::instance_s. As this member is initialized only once (for a given T), the initialization will take place in some of the translation units, but there's no way to say which one, and the standard cannot not guarantee that the initialization will occur before the first use of static_instantiation::holder<T> if that use happens at dynamic initialization time. The following shows the problem: ***foo.hpp*** #include <singleton.hpp> struct foo { foo():initialized(true){} bool initialized; }; typedef ste::pattern::singleton< foo, ste::pattern::static_instantiation
foo_singleton_type;
***tunit1.cpp*** #include "foo.hpp" bool b1=foo_singleton_type::instance()->initialized; ***tunit2.cpp*** #include "foo.hpp" bool b2=foo_singleton_type::instance()->initialized; ***main.cpp*** #include <iostream> extern bool b1; extern bool b2; int main() { std::cout<<"b1: "<<b1<<std::endl; std::cout<<"b2: "<<b1<<std::endl; } ****** I've tried the program composed of main.cpp, tunit1.cpp and tunit2.cpp in GCC 3.2 and the program output is not always what one'd expect, but rather it depends haphazardly on the order the translation units are compiled: g++ ... main.cpp tunit1.cpp tunit2.cpp output: b1: 1 b2: 1 g++ ... main.cpp tunit2.cpp tunit1.cpp output: b1: 0 b2: 0 g++ ... tunit1.cpp main.cpp tunit2.cpp output: b1: 1 b2: 1 g++ ... tunit1.cpp tunit2.cpp main.cpp output: b1: 1 b2: 1 g++ ... tunit2.cpp main.cpp tunit1.cpp output: b1: 0 b2: 0 g++ ... tunit2.cpp tunit1.cpp main.cpp output: b1: 0 b2: 0 You can solve this by combining a Meyers singleton with some static initialization forcing technique: class static_instantiation { template <typename T> struct init_forcer { init_forcer() { T* p; static_instantiation::make<T>(p); } void do_nothing(){} static init_forcer<T> init_forcer_s; }; protected: template <typename T> static void make(T*& p) { init_forcer<T>::init_forcer_s.do_nothing(); static T instance; p = &instance; } }; template <typename T> typename static_instantiation::init_forcer<T>::init_forcer static_instantiation::init_forcer<T>::init_forcer::init_forcer_s; This technique is used for instance by Boost.Pool, see boost/pool/detail/singleton.hpp. Hope this helps, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On 5/9/07, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Gregory Dai ha escrito:
On 5/8/07, Medland, Thomas M <thomas.medland@lehman.com> wrote:
Hi,
I have just moved company and in my old company I used to use a RogueWave singleton class. I was looking to use the boost singleton class. However after looking at the implementation I saw there was no private default copy constructor or assignment operator. Does this
not
mean that I could create multiple instances of my singleton via assignment or some other form of copying? I saw some discussion of a better singleton representation in boost and I was wondering what the status of this was, and I was also wondering what other people use for their singletons?
Thanks Tom
Well, I use the following. It's pretty simple and it works.
[...]
Hello Greg, I think there's a potential problem with your static_instantiation policy (or at least a limitation in applicability) due to its relying on the class template static member static_instantiation::holder<T>::instance_s. As this member is initialized only once (for a given T), the initialization will take place in some of the translation units, but there's no way to say which one, and the standard cannot not guarantee that the initialization will occur before the first use of static_instantiation::holder<T> if that use happens at dynamic initialization time.
Thanks for pointing it out, Joaquín. I've not used the static_instantiation though it's there. I found myself use lazy_instantiation, which is the default, all the time. <snip> You can solve this by combining a Meyers singleton with some static
initialization forcing technique:
class static_instantiation { template <typename T> struct init_forcer { init_forcer() { T* p; static_instantiation::make<T>(p); }
void do_nothing(){}
static init_forcer<T> init_forcer_s; };
protected: template <typename T> static void make(T*& p) { init_forcer<T>::init_forcer_s.do_nothing(); static T instance; p = &instance; } };
Isn't this kind of equivalent to the local_static_instantiation (the second policy)? In general, we use local static storage to avoid static class member construction, don't we? In other words, shall we say that the static_instantiation (instantiation policy) is there for illustration purpose only, not for applications in production. template <typename T>
typename static_instantiation::init_forcer<T>::init_forcer static_instantiation::init_forcer<T>::init_forcer::init_forcer_s;
This technique is used for instance by Boost.Pool, see boost/pool/detail/singleton.hpp. Hope this helps,
Thanks again. Greg

Gregory Dai ha escrito:
On 5/9/07, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Hello Greg, I think there's a potential problem with your static_instantiation policy [...] You can solve this by combining a Meyers singleton with some static initialization forcing technique: [...] Isn't this kind of equivalent to the local_static_instantiation (the second policy)? In general, we use local static storage to avoid static class member construction, don't we?
These policies work differently: local_static_instantiation creates the singleton the first time make() is called, be it in initialization time or after main() has begun; while static_instantiation guarantees that the creation always happens in initialization time.
In other words, shall we say that the static_instantiation (instantiation policy) is there for illustration purpose only, not for applications in production.
I'd say there is an important use case for static_instantiation which local_static_instantiation does not cover: if no threads are launched before main() begins, which is an extremely common situation, then the automatic creation of the singleton in initialization time is naturally thread safe, and so singleton<...>::instance need not be mutex-protected even if in a multithreaded app.. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On 5/9/07, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Gregory Dai ha escrito:
On 5/9/07, Joaquín Mª López Muñoz <joaquin@tid.es> wrote:
Hello Greg, I think there's a potential problem with your static_instantiation policy [...] You can solve this by combining a Meyers singleton with some static initialization forcing technique: [...] Isn't this kind of equivalent to the local_static_instantiation (the second policy)? In general, we use local static storage to avoid static class member construction, don't we?
These policies work differently: local_static_instantiation creates the singleton the first time make() is called, be it in initialization time or after main() has begun; while static_instantiation guarantees that the creation always happens in initialization time.
In other words, shall we say that the static_instantiation (instantiation policy) is there for illustration purpose only, not for applications in production.
I'd say there is an important use case for static_instantiation which local_static_instantiation does not cover: if no threads are launched before main() begins, which is an extremely common situation, then the automatic creation of the singleton in initialization time is naturally thread safe, and so singleton<...>::instance need not be mutex-protected even if in a multithreaded app..
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
You've got the final word, Master of Rome! Cheers, Greg
participants (5)
-
Gregory Dai
-
Joaquín Mª López Muñoz
-
Marius Lazer
-
Mathias Gaunard
-
Medland, Thomas M