///////////////////////////////////////////////////////////////// // const_val.h #ifndef CONST_VAL__H #define CONST_VAL__H // ... template< class type> struct const_val_traits { typedef type internal_type; typedef const type & outer_type; static outer_type get( const internal_type & val) { return val; } }; namespace Private { template< class char_type> struct const_val_traits_for_charstr { typedef std::basic_string< char_type> internal_type; typedef const char_type * outer_type; static outer_type get( const internal_type & val) { return val.c_str(); } }; }; template<> struct const_val_traits< char *> : public Private::const_val_traits_for_charstr< char> {}; template<> struct const_val_traits< signed char *> : public Private::const_val_traits_for_charstr< signed char> {}; template<> struct const_val_traits< unsigned char *> : public Private::const_val_traits_for_charstr< unsigned char> {}; template<> struct const_val_traits< wchar_t *> : public Private::const_val_traits_for_charstr< wchar_t> {}; template<> struct const_val_traits< const char *> : public Private::const_val_traits_for_charstr< char> {}; template<> struct const_val_traits< const signed char *> : public Private::const_val_traits_for_charstr< signed char> {}; template<> struct const_val_traits< const unsigned char *> : public Private::const_val_traits_for_charstr< const unsigned char> {}; template<> struct const_val_traits< const wchar_t *> : public Private::const_val_traits_for_charstr< wchar_t> {}; ///////////////////////////////////////////////////////////////// // const_val_base template< class type> class const_val_base { typedef typename const_val_traits< type>::internal_type internal_type; typedef typename const_val_traits< type>::outer_type outer_type; // ... protected: const_val_base() : m_val( internal_type() ), m_bInitialized( false) { if ( constants_and_dependents::are_initialized() ) throw std::runtime_error( "cannot initialize constants after " "constants_and_dependents::initialize() has been called.\n" "(constants are meant to be static and global.\n\n)" "use get_prop_val< type> instead !!!"); } outer_type get() const { check_val(); return const_val_traits< type>::get( m_val); } // ... protected: internal_type m_val; bool m_bInitialized; }; #endif ////////////////////////////////////////////////////////////////////////// // dependent_static.h #ifndef DEPENDENT_STATIC__H #define DEPENDENT_STATIC__H // ... namespace Private { template< class type> struct autoinitialize_if_called_after_initialize { autoinitialize_if_called_after_initialize( collect_parameters_base< type> *pInitializer, type *& pVal) { if ( constants_and_dependents::are_initialized() ) { pInitializer->initialize( pVal); } } }; } /* postpones initialization of static variable (it's initialized when you call initialize_static) * / class dependent_static : // so that we can register this object, to be initialized later public Private::dependent_static_base, // don't allow built-in as dependent statics! private Private::disallow_fundamental< type> { public: template< class type01, class type02, ... > dependent_static( type01 val01, type02 val02, ...) : m_pVal( 0), m_pInitializer( new_collect_parameters< type>( val01, val02, ... )), m_autoinitializer( m_pInitializer, m_pVal) {} // ... private: collect_parameters_base< type> *m_pInitializer; type * m_pVal; // its constructor is called LAST; this is very important, // since on its constructor, we rely on the fact that m_pInitializer and m_pVal // have been constructed !!! Private::autoinitialize_if_called_after_initialize< type> m_autoinitializer; }; // dependent_static // ... #endif // DEPENDENT_STATIC__H |