• Main Page
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/export/development/ViennaData/release/ViennaData-1.0.1/viennadata/traits/data_container.hpp

Go to the documentation of this file.
00001 /* =======================================================================
00002    Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
00003    http://www.iue.tuwien.ac.at
00004                              -----------------
00005                      ViennaData - The Vienna Data Storage Library
00006                              -----------------
00007 
00008    authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
00009 
00010    license:    MIT (X11), see file LICENSE in the ViennaData base directory
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     // 8 possibilities in total:
00032     // [pointer based|id based] identification
00033     // [full key|no key] dispatch
00034     // [sparse|dense] storage
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       //by default, do nothing: (some map-based mechanism)
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       //id based identification:
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;  // with key object based dispatch    
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;  // with key object based dispatch    
00120       
00122       template <typename ContainerType, typename IdType>
00123       static typename data_type_reference<DataType, ContainerType>::type  //DataType &    does not work here for std::vector<bool> as ContainerType!
00124       access(ContainerType & cont, IdType const & id, KeyType const & key)
00125       {
00126         return cont[id];
00127       }
00128 
00129       //also allow access without key here, because uniquely defined:
00131       template <typename ContainerType, typename IdType>
00132       static typename data_type_reference<DataType, ContainerType>::type  //DataType &    does not work here for std::vector<bool> as ContainerType!
00133       access(ContainerType & cont, IdType const & id)
00134       {
00135         return cont[id];
00136       }
00137     };
00138     
00140     
00141     //general case: call erase of the underlying map-type
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       //default case:
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     //dense storage when providing ID
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           //std::cout << "Auto resize to " << s + 1 << std::endl;
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       // the datatype:
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         //std::cout << "Accessing sparse data by pointer" << std::endl;
00347         
00348         //make sure that for dense data access the resizing is done:
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         //make sure that for dense data access the resizing is done:
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         //TODO: can be improved if cont_src[id_src] is actually empty, because there is no move necessary then...
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         //cont[object_identifier<ObjectType>::id(element)].erase(key);
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         //container_auto_resize<StorageTag>::apply(cont, viennadata::config::object_identifier<ObjectType>::get(obj));
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   } //namespace traits
00481 
00482 } // namespace viennadata
00483 
00484 
00485 #endif

Generated on Wed Sep 14 2011 18:17:05 for ViennaData - The Vienna Data Storage Library by  doxygen 1.7.1