
I am trying to decide on the best interface for the multiton to provide. Some background: The singleton interface consists of three smart pointer types: singleton_ptr, const_singleton_ptr, and singleton_ref. Instances of these always automagically refer to the singleton instance. With regard to multi threading, when an operation is performed through a singleton_ptr, an exclusive lock is obtained for the duration of the operation. A const_singleton_ptr behaves similarly, but it acquired a shared lock instead, and only const members of the singleton instance can be accessed. A singleton_ref is considered to be a dereferenced singleton_ptr, so it owns an exclusive lock on the instance for its entire lifetime. It is implicitly convertible to a raw reference to Type, and as such is ideal to use as a proxy to the instance which locks it for the duration of a function call. Ex: void foo ( Type & ); void bar ( ) { // pass the singleton to foo and simultaneously lock the operation foo ( singleton_ref < Type > ( ) ); } Ideally, I would like the multiton to provide a similar interface. I would picture doing this by providing a multiton_ptr, const_multiton_ptr, and multiton_ref, which all take a key to the instance as a constructor param. Question 1) Should multiton_ptrs be copy constructible or assignable? What about multiton_refs? Keep in mind that a multiton_ref owns a lock directly, and thus would need to switch locks if redirected to a different instance. Question 2) Should the multiton_ptr and const_multiton_ptr also function as iterators? If so, should dereferencing them result in a pointer to a pair < const Key &, Type & >, or just a regular pointer to Type? Also, since the container itself is not exposed, how should I provide access to 'begin' and 'end'? Is it sufficient to provide a multiton_ptr constructor which takes an enum, and have that enum define the values begin and end? Question 3) Although each singleton instance in a multiton has its own mutex (assuming a multi threaded policy), operations which can change the state of the multiton container itself also need to be locked with a separate mutex. Thus far, the only operation of this nature that I can see is when a pointer to an instance with a previously unused key is created. However, if client code is using a multiton_ptr as an iterator in a loop, that whole loop needs to be locked with the same mutex as well, lest another thread incidentally create a new instance while the loop is in progress. Should multiton_ptr provide public nested read and write lock types to give client code this access, or should it provide some sort of for_each algorithm instead, which does the locking automatically? Question 4) Should the container used by the multiton become an additional optional policy? A regular map just won't cut it if the multiton needs its instances to exist in shared memory. A few more notes: * The singleton and multiton no longer have any inheritance requirements. Hence, even singleton_ptr < int > is valid, along with any other type one can think of. * An uncreatable base is provided which does use CRTP. If used, uncreatable must also be provided with the factory to use internally. Use of this is completely optional, and makes it completely and absolutely impossible for client code to create singleton instances, no matter how hard it tries to hack around it. (If there is interest in the semantics of this, I will post a more complete description). If anyone feels my design is partially or completely off and has better ideas please let me know. -Jason