lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
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