00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef VIENNADATA_TRAITS_DATA_CONTAINER_HPP
00014 #define VIENNADATA_TRAITS_DATA_CONTAINER_HPP
00015
00016 #include <map>
00017
00018 #include "viennadata/forwards.h"
00019 #include "viennadata/config/object_identifier.hpp"
00020 #include "viennadata/config/key_dispatch.hpp"
00021 #include "viennadata/config/storage.hpp"
00022
00027 namespace viennadata
00028 {
00029 namespace traits{
00030
00031
00032
00033
00034
00035
00036
00038 template <typename KeyDispatchTag>
00039 struct IS_ACCESS_WITHOUT_KEY_ALLOWED
00040 {
00041 typedef typename KeyDispatchTag::ERROR_ACCESS_CALLED_WITHOUT_KEY_ARGUMENT check_type;
00042 };
00043
00045 template <>
00046 struct IS_ACCESS_WITHOUT_KEY_ALLOWED<type_key_dispatch_tag>
00047 {
00048 typedef void check_type;
00049 };
00050
00051
00053 template <typename DataType, typename ContainerType>
00054 struct data_type_reference
00055 {
00056 typedef DataType & type;
00057 };
00058
00059 template <>
00060 struct data_type_reference<bool, std::vector<bool> >
00061 {
00062 typedef std::vector<bool>::reference type;
00063 };
00064
00065
00066
00068 template <typename ContainerType,
00069 typename ObjectIdentificationTag,
00070 typename StorageTag>
00071 struct container_reservation_dispatcher
00072 {
00073
00074 static void reserve(ContainerType & container, long num) { }
00075 };
00076
00078 template <typename ContainerType>
00079 struct container_reservation_dispatcher<ContainerType, object_provided_id, dense_data_tag>
00080 {
00081
00082 static void reserve(ContainerType & container, long num) { container.resize(num); }
00083 };
00084
00085
00086
00087
00088
00090
00096 template <typename KeyType,
00097 typename DataType,
00098 typename KeyDispatchTag>
00099 struct container_key_value_pair
00100 {
00101 typedef std::map< KeyType, DataType > key_DataType;
00102
00104 template <typename ContainerType,
00105 typename IdType>
00106 static DataType & access(ContainerType & cont,
00107 IdType const & id,
00108 KeyType const & key)
00109 {
00110 return cont[id][key];
00111 }
00112 };
00113
00115 template <typename KeyType,
00116 typename DataType>
00117 struct container_key_value_pair <KeyType, DataType, type_key_dispatch_tag>
00118 {
00119 typedef DataType key_DataType;
00120
00122 template <typename ContainerType, typename IdType>
00123 static typename data_type_reference<DataType, ContainerType>::type
00124 access(ContainerType & cont, IdType const & id, KeyType const & key)
00125 {
00126 return cont[id];
00127 }
00128
00129
00131 template <typename ContainerType, typename IdType>
00132 static typename data_type_reference<DataType, ContainerType>::type
00133 access(ContainerType & cont, IdType const & id)
00134 {
00135 return cont[id];
00136 }
00137 };
00138
00140
00141
00153 template <typename KeyType,
00154 typename DataType,
00155 typename ObjectIdentificationTag,
00156 typename KeyDispatchTag,
00157 typename StorageTag>
00158 struct container_erasure_dispatcher
00159 {
00160
00162 template <typename ContainerType, typename IdType>
00163 static void erase(ContainerType & cont, IdType const & id, KeyType const & key)
00164 {
00165 cont[id].erase(key);
00166 }
00167
00169 template <typename ContainerType, typename IdType>
00170 static void erase(ContainerType & cont, IdType const & id)
00171 {
00172 cont.erase(id);
00173 }
00174
00175 };
00176
00178 template <typename KeyType,
00179 typename DataType,
00180 typename ObjectIdentificationTag,
00181 typename StorageTag>
00182 struct container_erasure_dispatcher < KeyType,
00183 DataType,
00184 ObjectIdentificationTag,
00185 type_key_dispatch_tag,
00186 StorageTag >
00187 {
00189 template <typename ContainerType, typename IdType>
00190 static void erase(ContainerType & cont, IdType const & id, KeyType const & key)
00191 {
00192 cont.erase(id);
00193 }
00194
00196 template <typename ContainerType, typename IdType>
00197 static void erase(ContainerType & cont, IdType const & id)
00198 {
00199 cont.erase(id);
00200 }
00201 };
00202
00204 template <typename KeyType, typename DataType, typename KeyDispatchTag>
00205 struct container_erasure_dispatcher < KeyType, DataType, object_provided_id, KeyDispatchTag, dense_data_tag >
00206 {
00207 typedef typename container_key_value_pair< KeyType,
00208 DataType,
00209 KeyDispatchTag >::key_DataType key_DataType;
00210
00212 template <typename ContainerType, typename IdType>
00213 static void erase(ContainerType & cont, IdType const & id, KeyType const & key)
00214 {
00215 cont[id] = key_DataType();
00216 }
00217
00219 template <typename ContainerType, typename IdType>
00220 static void erase(ContainerType & cont, IdType const & id)
00221 {
00222 cont[id] = key_DataType();
00223 }
00224 };
00225
00227 template <typename KeyType, typename DataType>
00228 struct container_erasure_dispatcher < KeyType, DataType, object_provided_id, type_key_dispatch_tag, dense_data_tag >
00229 {
00230 typedef typename container_key_value_pair< KeyType,
00231 DataType,
00232 type_key_dispatch_tag >::key_DataType key_DataType;
00233
00235 template <typename ContainerType, typename IdType>
00236 static void erase(ContainerType & cont, IdType const & id, KeyType const & key)
00237 {
00238 cont[id] = key_DataType();
00239 }
00240
00242 template <typename ContainerType, typename IdType>
00243 static void erase(ContainerType & cont, IdType const & id)
00244 {
00245 cont[id] = key_DataType();
00246 }
00247 };
00248
00249
00250
00252
00253
00255 template <typename KeyType,
00256 typename DataType,
00257 typename ObjectType,
00258 typename ObjectIdentificationTag,
00259 typename KeyDispatchTag,
00260 typename StorageTag>
00261 struct container_storage
00262 {
00263
00264 typedef typename viennadata::config::object_identifier<ObjectType>::id_type id_type;
00265 typedef std::map< id_type,
00266 typename container_key_value_pair< KeyType,
00267 DataType,
00268 KeyDispatchTag >::key_DataType
00269 > container_type;
00270
00272 static void reserve(container_type & cont, long num) { }
00273 };
00274
00275
00277 template <typename KeyType,
00278 typename DataType,
00279 typename ObjectType,
00280 typename KeyDispatchTag>
00281 struct container_storage <KeyType, DataType, ObjectType,
00282 object_provided_id, KeyDispatchTag, dense_data_tag>
00283 {
00284 typedef typename viennadata::config::object_identifier<ObjectType>::id_type id_type;
00285 typedef std::vector< typename container_key_value_pair< KeyType,
00286 DataType,
00287 KeyDispatchTag >::key_DataType
00288 > container_type;
00289
00291 static void reserve(container_type & cont, long num) { cont.resize(num); }
00292 };
00293
00294
00296 template <typename StorageTag>
00297 struct container_auto_resize
00298 {
00299 template <typename ContainerType, typename SizeType>
00300 static void apply(ContainerType const & c, SizeType const & s) {}
00301 };
00302
00304 template <>
00305 struct container_auto_resize<dense_data_tag>
00306 {
00307 template <typename ContainerType>
00308 static void apply(ContainerType & c, size_t s)
00309 {
00310 if (s >= c.size())
00311 {
00312
00313 c.resize(s + 1);
00314 }
00315 }
00316 };
00317
00327 template <typename KeyType,
00328 typename DataType,
00329 typename ObjectType,
00330 typename ObjectIdentificationTag = typename viennadata::config::object_identifier<ObjectType>::tag,
00331 typename KeyDispatchTag = typename viennadata::config::key_dispatch<KeyType>::tag,
00332 typename StorageTag = typename viennadata::config::storage<KeyType, DataType, ObjectType>::tag>
00333 struct container
00334 {
00335
00336 typedef typename container_storage<KeyType, DataType, ObjectType,
00337 ObjectIdentificationTag,
00338 KeyDispatchTag,
00339 StorageTag>::container_type container_type;
00340
00341 typedef typename data_type_reference<DataType, container_type>::type reference;
00342
00344 static reference access(container_type & cont, ObjectType const & obj, KeyType const & key)
00345 {
00346
00347
00348
00349 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00350
00351 return container_key_value_pair <KeyType,
00352 DataType,
00353 KeyDispatchTag>::access(cont, viennadata::config::object_identifier<ObjectType>::get(obj), key);
00354 }
00355
00357 static reference access(container_type & cont, ObjectType const & obj)
00358 {
00359 typedef typename IS_ACCESS_WITHOUT_KEY_ALLOWED<KeyDispatchTag>::check_type some_type;
00360
00361
00362 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00363
00364 return container_key_value_pair <KeyType,
00365 DataType,
00366 KeyDispatchTag>::access(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00367 }
00368
00370 template <typename ContainerSrcType, typename ObjectSrcType>
00371 static void copy(ContainerSrcType & cont_src,
00372 ObjectSrcType const & obj_src,
00373 container_type & cont_dest,
00374 ObjectType const & obj_dest)
00375 {
00376 container_auto_resize<StorageTag>::apply(cont_src, viennadata::config::object_identifier<ObjectSrcType>::get(obj_src));
00377 container_auto_resize<StorageTag>::apply(cont_dest, viennadata::config::object_identifier<ObjectType>::get(obj_dest));
00378
00379
00380 cont_dest[viennadata::config::object_identifier<ObjectType>::get(obj_dest)] =
00381 cont_src[viennadata::config::object_identifier<ObjectSrcType>::get(obj_src)];
00382 }
00383
00384
00386 static void reserve(container_type & cont, long num)
00387 {
00388 container_storage<KeyType, DataType, ObjectType,
00389 ObjectIdentificationTag,
00390 KeyDispatchTag,
00391 StorageTag>::reserve(cont, num);
00392 }
00393
00395 static void erase(container_type & cont,
00396 ObjectType const & obj,
00397 KeyType const & key)
00398 {
00399 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00400
00401
00402 container_erasure_dispatcher<KeyType, DataType,
00403 ObjectIdentificationTag,
00404 KeyDispatchTag,
00405 StorageTag>::erase(cont, viennadata::config::object_identifier<ObjectType>::get(obj), key);
00406 }
00407
00409 static void erase(container_type & cont,
00410 ObjectType const & obj)
00411 {
00412 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00413
00414 container_erasure_dispatcher<KeyType, DataType,
00415 ObjectIdentificationTag,
00416 KeyDispatchTag,
00417 StorageTag>::erase(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00418 }
00419
00424 static DataType * find_impl(container_type & cont,
00425 ObjectType const & obj,
00426 KeyType const & key,
00427 type_key_dispatch_tag)
00428 {
00429 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00430 return &( cont[viennadata::config::object_identifier<ObjectType>::get(obj)] );
00431 }
00432
00437 static DataType * find_impl(container_type & cont,
00438 ObjectType const & obj,
00439 KeyType const & key,
00440 full_key_dispatch_tag)
00441 {
00442 container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
00443
00444 typename std::map< KeyType, DataType >::iterator it = cont[viennadata::config::object_identifier<ObjectType>::get(obj)].find(key);
00445 if (it == cont[viennadata::config::object_identifier<ObjectType>::get(obj)].end())
00446 return NULL;
00447
00448 return &(it->second);
00449 }
00450
00455 static DataType * find(container_type & cont,
00456 ObjectType const & obj,
00457 KeyType const & key)
00458 {
00459 return find_impl(cont, obj, key, KeyDispatchTag());
00460 }
00461
00466 static DataType * find(container_type & cont,
00467 ObjectType const & obj)
00468 {
00469
00470
00471 typename container_type::iterator it = cont.find(viennadata::config::object_identifier<ObjectType>::get(obj));
00472 if (it == cont.end())
00473 return NULL;
00474
00475 return &(it->second);
00476 }
00477
00478 };
00479
00480 }
00481
00482 }
00483
00484
00485 #endif