lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
property_collection.h
00001 /*****************************************************/
00002 /* lean Properties              (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_PROPERTIES_PROPERTY_COLLECTION
00006 #define LEAN_PROPERTIES_PROPERTY_COLLECTION
00007 
00008 #include <typeinfo>
00009 #include <vector>
00010 #include "../tags/noncopyable.h"
00011 
00012 namespace lean
00013 {
00014 namespace properties
00015 {
00016 
00018 template < class Class, class Description, class Vector = std::vector<Description> >
00019 class property_collection
00020 {
00021 private:
00022     typedef Vector property_vector;
00023     property_vector m_properties;
00024 
00025 public:
00027     typedef Description property_desc;
00029     typedef typename property_vector::const_iterator iterator;
00031     typedef typename property_vector::const_iterator const_iterator;
00032 
00034     property_collection() { }
00036     template <class Iterator>
00037     property_collection(Iterator begin, Iterator end)
00038         : m_properties(begin, end) { }
00040     template <class Range>
00041     property_collection(const Range &range)
00042         : m_properties(range.begin(), range.end()) { }
00043 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00044 
00045     property_collection(property_collection &&right)
00046         : m_properties( std::move(right.m_properties) ) { }
00047 #endif
00048 
00050     template <class Collection = property_collection>
00051     class inplace_builder
00052     {
00053     friend class property_collection;
00054 
00055     protected:
00057         Collection m_collection;
00058 
00059     public:
00061         inplace_builder() { }
00063         template <class Iterator>
00064         inplace_builder(Iterator begin, Iterator end)
00065             : m_collection(begin, end) { }
00067         template <class Range>
00068         inplace_builder(const Range &range)
00069             : m_collection(range) { }
00070 
00072         LEAN_INLINE inplace_builder& operator <<(const property_desc& propertyDesc)
00073         {
00074             m_collection.add(propertyDesc);
00075             return *this;
00076         }
00077     };
00079     property_collection(inplace_builder<> &right)
00080     {
00081         *this = right;
00082     }
00084     static LEAN_INLINE inplace_builder<> construct_inplace()
00085     {
00086         return inplace_builder<>();
00087     }
00089     template <class Iterator>
00090     static LEAN_INLINE inplace_builder<> construct_inplace(Iterator begin, Iterator end)
00091     {
00092         return inplace_builder<>(begin, end);
00093     }
00095     template <class Range>
00096     static LEAN_INLINE inplace_builder<> construct_inplace(const Range &range)
00097     {
00098         return inplace_builder<>(range);
00099     }
00100 
00101 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00102 
00103     LEAN_INLINE property_collection& operator =(property_collection &&right)
00104     {
00105         m_properties = std::move(right.m_properties);
00106         return *this;
00107     }
00108 #endif
00109 
00110     LEAN_INLINE property_collection& operator =(inplace_builder<> &right)
00111     {
00112 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00113         m_properties = std::move(right.m_collection.m_properties);
00114 #else
00115         using std::swap;
00116         swap(m_properties, right.m_collection.m_properties);
00117 #endif
00118         return *this;
00119     }
00120 
00122     LEAN_INLINE size_t add(const property_desc& propertyDesc)
00123     {
00124         size_t id = m_properties.size();
00125         m_properties.push_back(propertyDesc);
00126         return id;
00127     }
00128 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00129 
00130     LEAN_INLINE size_t add(property_desc&& propertyDesc)
00131     {
00132         size_t id = m_properties.size();
00133         m_properties.push_back( std::move(propertyDesc) );
00134         return id;
00135     }
00136 #endif
00137 
00139     LEAN_INLINE const property_desc& desc(size_t id) const
00140     {
00141         return m_properties[id];
00142     }
00143     
00145     LEAN_INLINE size_t count() const
00146     {
00147         return m_properties.size();
00148     }
00149 
00151     LEAN_INLINE const property_desc* data() const
00152     {
00153         return &m_properties.front();
00154     }
00156     LEAN_INLINE const property_desc* data_end() const
00157     {
00158         return &m_properties.back() + 1;
00159     }
00160 
00162     LEAN_INLINE const_iterator begin() const
00163     {
00164         return m_properties.begin();
00165     }
00167     LEAN_INLINE const_iterator end() const
00168     {
00169         return m_properties.end();
00170     }
00171 
00173     template <class Value>
00174     LEAN_INLINE bool set(Class &object, size_t id, const Value &value) const
00175     {
00176         return set(object, id, &value, 1);
00177     }
00179     template <class Value>
00180     LEAN_INLINE bool set(Class &object, size_t id, const Value *values, size_t count) const
00181     {
00182         return (id < m_properties.size())
00183             ? set_property(object, m_properties[id].setter, values, count)
00184             : false;
00185     }
00186 
00188     template <class Value>
00189     LEAN_INLINE bool get(const Class &object, size_t id, Value &value) const
00190     {
00191         return get(object, id, &value, 1);
00192     }
00194     template <class Value>
00195     LEAN_INLINE bool get(const Class &object, size_t id, Value *values, size_t count) const
00196     {
00197         return (id < m_properties.size())
00198             ? get_property(object, m_properties[id].getter, values, count)
00199             : false;
00200     }
00201 };
00202 
00203 } // namespace
00204 
00205 using properties::property_collection;
00206 
00207 } // namespace
00208 
00209 #endif