// Semantics Consulting's Tyr Library // http://www.semantics.org // // Copyright (c) 2003 by Stephen C. Dewhurst // // Permission to use, copy, modify, distribute, and sell this software // for any purpose is hereby granted without fee, provided that the above // copyright notice appears in all copies and that both that copyright // notice and this permission notice appear in supporting documentation. // The author makes no representations about the suitability of this // software for any purpose. It is provided "as is" without express // or implied warranty. // Expanding Monostate protopattern // Described in What Are You, Anyway? C/C++ Users Journal Experts Forum, 21, 8 (August 2003). #ifndef EXPANDINGMONOSTATE_H #define EXPANDINGMONOSTATE_H namespace Tyr { // // Expanding Monostate // // Ask for a member of a given type, creates members // automatically, as needed at compile time. // class Monostate { public: template T &get() { static T member; return member; } }; // // Indexed Expanding Monostate // // Allows different members of the same type. // class IndexedMonostate { public: template T &get() { static T member; return member; } }; // // Named Expanding Monostate // // Allows named monostate members. // template struct Name { typedef T Type; }; typedef Name anInt; typedef Name aDouble; class NamedMonostate { public: template typename N::Type &get( ) { static typename N::Type member; return member; } }; // // Named Expanding Monostate with traditional get/set. // class GSNamedMonostate { public: template void set( const typename N::Type &val ) { // This const_cast is actually safe, since we are // always actually getting a non-const object. // (Unless N::Type is const, then you get a compile error here.) const_cast(get()) = val; } template const typename N::Type &get( ) const { static typename N::Type member; return member; } }; } // namespace Tyr #endif