/////////////////////////////////////////////////////////////////////////////////////////////////// // File fem_props_repository.h #pragma once namespace fem { /////////////////////////////////////////////////////////////////////////////////////////////////// // The following CPropRepository class template, originally presented by Bjarne Stroustrup (http://www.research.att.com/~bs), // wraps a built-in array in a class that has no additional data members and therefore incurs no space overhead. // Unlike ordinary STL containers, allocates its array statically on the stack, just as built-in arrays do. // Most importantly, it provides the standard interface that other STL components recognize. // Exception to this commitment is that we dont allow non const direct access to the data members as this class enforces undo / redo support. // althought set_without_undo member function does not conform to the above requirement, it can easilly be located wherever used. // that is not the case if we enable: reference operator [] (sise_t i) // This class is designed for outmost efficiency. It has neither a constructor nor a destructor and all its member functions are inlined. template class CPropRepository { friend class boost::serialization::access; template void save(Archive & ar, const unsigned int /*version*/) const { ar & BOOST_SERIALIZATION_NVP(_t); } template void load(Archive & ar, const unsigned int /*version*/) { ar & BOOST_SERIALIZATION_NVP(_t); } BOOST_SERIALIZATION_SPLIT_MEMBER(); public: //uniform typedefs used in STL algorithms and containers typedef T value_type; typedef T* iterator; typedef const T * const_iterator; typedef T& reference; typedef const T& const_reference; // member functions of typical STL containers: size_t size () const { return SZ; } // const versions const_iterator begin() const { return _t; } const_iterator end () const { return _t + SZ; } const_reference operator [] (size_t i) const { return _t[i]; } //// non const access functions versions (supported only for boost::serialization. should never be used elsewhere!) //operator T* () { return _t; } //iterator begin() { return _t; } //iterator end () { return _t + SZ; } //reference operator[] (size_t i) { return _t[i]; } // checked access const_reference get(size_t i) const { ASSERT(i>=0 && i=0 && i=0 && iIsEnableUndo()) (fem::s_pUndoRedo)->AddCommand((fem::s_pUndoRedo)->GetFemUndoRedoImpl()->CreateCmdPropRepository_Set(*this, i, _t[i]), ctCmd); _t[i] = t; } } void set(const value_type t[SZ], undo::eCmdType ctCmd = undo::cmdDo) { if ((fem::s_pUndoRedo) != NULL && ctCmd != undo::cmdRollback && (fem::s_pUndoRedo)->IsEnableUndo()) (fem::s_pUndoRedo)->AddCommand((fem::s_pUndoRedo)->GetFemUndoRedoImpl()->CreateCmdPropRepository_SetSZ(*this, _t), ctCmd); for(size_t i=0; i> _t[i]; } } friend CArchive& operator << (CArchive& ar, const CPropRepository& p) { for (size_t i=0; i> (CArchive& ar, CPropRepository& p) { for (size_t i=0; i> p._t[i]; return ar; } private: value_type _t[SZ]; }; } // namespace fem //either use macro definitions: //BOOST_CLASS_IMPLEMENTATION(nvp, boost::serialization::level_type::object_serializable) //BOOST_CLASS_TRACKING(nvp, boost::serialization::track_never) //or original definitions of the above: //fem::CPropRepository namespace boost { namespace serialization { template struct implementation_level< fem::CPropRepository > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT( int, value = implementation_level::type::value ); }; //fem::CPropRepository objects are generally created on the stack and are never tracked template struct tracking_level< fem::CPropRepository > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT( int, value = tracking_level::type::value ); }; } }