00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #ifndef MESH3D__ATTRIBUTE_MAP__INL
00028 #define MESH3D__ATTRIBUTE_MAP__INL
00029
00030 namespace mesh3d {
00031
00032 template<typename Key>
00033 inline attribute_map_base<Key>::attribute_map_base()
00034 {
00035 }
00036
00037 template<typename Key>
00038 inline attribute_map_base<Key>::~attribute_map_base()
00039 {
00040 }
00041
00042 template<typename Key, typename Value>
00043 inline attribute_map<Key, Value>::attribute_map()
00044 : m_is_optimized(true)
00045 , m_is_inserting(false)
00046 {
00047 }
00048
00049 template<typename Key, typename Value>
00050 inline bool attribute_map<Key, Value>::empty() const
00051 {
00052 return m_entries.empty();
00053 }
00054
00055 template<typename Key, typename Value>
00056 inline index_type attribute_map<Key, Value>::size() const
00057 {
00058 assert(m_entries.size() < std::numeric_limits<index_type>::max());
00059 return static_cast<index_type>(m_entries.size());
00060 }
00061
00062 template<typename Key, typename Value>
00063 inline void attribute_map<Key, Value>::begin_insertion(
00064 index_type estimated_count)
00065 {
00066 assert(!is_inserting());
00067
00068 m_entries.clear();
00069 m_entries.reserve(estimated_count);
00070
00071 m_is_optimized = false;
00072 m_is_inserting = true;
00073 }
00074
00075 template<typename Key, typename Value>
00076 inline void attribute_map<Key, Value>::insert(
00077 Key const &key,
00078 Value const &value
00079 )
00080 {
00081 assert(is_inserting());
00082 assert(m_entries.size() + 1 < std::numeric_limits<index_type>::max());
00083
00084 entry e;
00085 e.key = key;
00086 e.value = value;
00087
00088 #if _HAS_ITERATOR_DEBUGGING
00089 assert(
00090 std::find(m_entries.begin(), m_entries.end(), e) == m_entries.end()
00091 );
00092 #endif
00093
00094 m_entries.push_back(e);
00095 }
00096
00097 template<typename Key, typename Value>
00098 inline void attribute_map<Key, Value>::end_insertion()
00099 {
00100 assert(is_inserting());
00101
00102 m_is_inserting = false;
00103
00104 optimize();
00105 }
00106
00107 template<typename Key, typename Value>
00108 inline bool attribute_map<Key, Value>::is_inserting() const
00109 {
00110 return m_is_inserting;
00111 }
00112
00113 template<typename Key, typename Value>
00114 inline void attribute_map<Key, Value>::set_value(
00115 Key const &key,
00116 Value const &value
00117 )
00118 {
00119 assert(!is_inserting());
00120
00121 entry_container::iterator i = find(key);
00122 if(i == m_entries.end())
00123 {
00124 insert_entry(key, value);
00125 }
00126 else
00127 {
00128 i->value = value;
00129 }
00130 }
00131
00132 template<typename Key, typename Value>
00133 inline Value attribute_map<Key, Value>::value(Key const &key) const
00134 {
00135 assert(!is_inserting());
00136
00137 entry_container::const_iterator i = find(key);
00138 if(i != m_entries.end())
00139 {
00140 return i->value;
00141 }
00142 else
00143 {
00144 throw key_not_found_exception<Key>(key);
00145 }
00146 }
00147
00148 template<typename Key, typename Value>
00149 inline bool attribute_map<Key, Value>::has(Key const& key) const
00150 {
00151 assert(!is_inserting());
00152
00153 return find(key) != m_entries.end();
00154 }
00155
00156 template<typename Key, typename Value>
00157 inline void attribute_map<Key, Value>::optimize()
00158 {
00159 assert(!is_inserting());
00160
00161 std::sort(m_entries.begin(), m_entries.end());
00162
00163 m_is_optimized = true;
00164 }
00165
00166 template<typename Key, typename Value>
00167 inline bool attribute_map<Key, Value>::is_optimized() const
00168 {
00169 return m_is_optimized;
00170 }
00171
00172 template<typename Key, typename Value>
00173 inline std::type_info const &attribute_map<Key, Value>::value_type_id() const
00174 {
00175 return typeid(Value);
00176 }
00177
00178 template<typename Key, typename Value>
00179 inline typename attribute_map<Key, Value>::entry_container::const_iterator
00180 attribute_map<Key, Value>::find(Key const &key) const
00181 {
00182 entry e;
00183 e.key = key;
00184
00185 if(m_is_optimized)
00186 {
00187 std::pair<entry_container::const_iterator,entry_container::const_iterator>
00188 p = std::equal_range(m_entries.begin(), m_entries.end(), e);
00189 return p.first != p.second ? p.first : m_entries.end();
00190 }
00191 else
00192 {
00193 return std::find(m_entries.begin(), m_entries.end(), e);
00194 }
00195 }
00196
00197 template<typename Key, typename Value>
00198 inline typename attribute_map<Key, Value>::entry_container::iterator
00199 attribute_map<Key, Value>::find(Key const &key)
00200 {
00201 entry e;
00202 e.key = key;
00203
00204 if(m_is_optimized)
00205 {
00206 std::pair<entry_container::iterator,entry_container::iterator>
00207 p = std::equal_range(m_entries.begin(), m_entries.end(), e);
00208 return p.first != p.second ? p.first : m_entries.end();
00209 }
00210 else
00211 {
00212 return std::find(m_entries.begin(), m_entries.end(), e);
00213 }
00214 }
00215
00216 template<typename Key, typename Value>
00217 inline void attribute_map<Key, Value>::insert_entry(
00218 Key const &key,
00219 Value const &value
00220 )
00221 {
00222 if(
00223 !m_entries.empty() &&
00224 (key < m_entries.back().key)
00225 )
00226 {
00227 m_is_optimized = false;
00228 }
00229
00230 entry e;
00231 e.key = key;
00232 e.value = value;
00233 m_entries.push_back(e);
00234 }
00235
00236 template<typename Key, typename Value>
00237 inline bool attribute_map<Key, Value>::entry::operator==(entry const &other) const
00238 {
00239 return key == other.key;
00240 }
00241
00242 template<typename Key, typename Value>
00243 inline bool attribute_map<Key, Value>::entry::operator<(entry const &other) const
00244 {
00245 return key < other.key;
00246 }
00247
00248 }
00249
00250 #endif
00251