value_type_adapter.hpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00031 
00032 // Permission to use, copy, modify, sell, and distribute this software
00033 // is hereby granted without fee, provided that the above copyright
00034 // notice appears in all copies, and that both that copyright notice and
00035 // this permission notice appear in supporting documentation. None of
00036 // the above authors, nor IBM Haifa Research Laboratories, make any
00037 // representation about the suitability of this software for any
00038 // purpose. It is provided "as is" without express or implied warranty.
00039 
00045 #ifndef VALUE_TYPE_ADAPTER_HPP
00046 #define VALUE_TYPE_ADAPTER_HPP
00047 
00048 #include <ext/pb_assoc/detail/value_type_adapter/ref_pair.hpp>
00049 #include <ext/pb_assoc/detail/assoc_cntnr_base.hpp>
00050 #include <ext/pb_assoc/detail/value_type_adapter/invalidation_guarantee_selector.hpp>
00051 #include <ext/pb_assoc/detail/type_utils.hpp>
00052 #include <utility>
00053 #include <algorithm>
00054 #include <tr1/type_traits>  // for aligned_storage/alignment_of
00055 
00056 namespace pb_assoc
00057 {
00058 
00059   namespace detail
00060   {
00061 
00062 #define PB_ASSOC_STATIC_ASSERT(UNIQUE, E) \
00063     typedef \
00064         pb_assoc::detail::static_assert_dummy_class< \
00065             sizeof(pb_assoc::detail::static_assert<(bool)(E)>)> \
00066             UNIQUE##static_assert_type
00067 
00068 #define PB_ASSOC_CLASS_T_DEC \
00069     template< \
00070         typename Key, \
00071         typename Data, \
00072         class DS_Tag, \
00073         class Policy_Tl, \
00074         class Allocator, \
00075         int Mapping_Level>
00076 
00077 #define PB_ASSOC_CLASS_C_DEC \
00078     value_type_adapter< \
00079         Key, \
00080         Data, \
00081         DS_Tag, \
00082         Policy_Tl, \
00083         Allocator, \
00084         Mapping_Level>
00085 
00086 #define PB_ASSOC_BASE_C_DEC \
00087     cond_type< \
00088         Mapping_Level != 1, \
00089         value_type_adapter< \
00090             Key, \
00091             Data, \
00092             DS_Tag, \
00093             Policy_Tl, \
00094             Allocator, \
00095             Mapping_Level - 1>, \
00096         typename assoc_cntnr_base< \
00097             Key, \
00098             Data, \
00099             DS_Tag, \
00100             Policy_Tl, \
00101             Allocator>::type>::type
00102 
00103     template<typename Key,
00104          typename Data,
00105          class DS_Tag,
00106          class Policy_Tl,
00107          class Allocator,
00108          int Mapping_Level>
00109     struct value_type_adapter : public PB_ASSOC_BASE_C_DEC
00110     {
00111 
00112     private:
00113       typedef typename PB_ASSOC_BASE_C_DEC my_base;
00114 
00115       typedef typename my_base::data_type my_base_data_type;
00116 
00117       enum
00118     {
00119       same_alloc_type =
00120       is_same_type<
00121       typename my_base::allocator::template rebind<
00122       char>::other,
00123       typename my_base_data_type::allocator::template rebind<
00124       char>::other>::value
00125     };
00126 
00127       PB_ASSOC_STATIC_ASSERT(wrong_level, Mapping_Level > 0);
00128 
00129       PB_ASSOC_STATIC_ASSERT(must_be_same_alloc, same_alloc_type);
00130 
00131 #include <ext/pb_assoc/detail/value_type_adapter/value_type_traits.hpp>
00132 #include <ext/pb_assoc/detail/value_type_adapter/it_value_type_traits.hpp>
00133 
00134       typedef
00135       it_value_type_traits_<
00136     typename base_it_key_type<
00137     my_base,
00138     Mapping_Level == 1>::type,
00139     typename my_base_data_type::const_key_reference,
00140     typename cond_type<
00141     is_same_type<
00142     typename my_base_data_type::data_type,
00143     null_data_type>::value,
00144     null_data_type,
00145     typename my_base_data_type::data_reference>::type,
00146     typename my_base_data_type::reference,
00147     typename my_base::allocator>
00148       it_value_type_traits_t;
00149 
00150 #include <ext/pb_assoc/detail/value_type_adapter/iterator.hpp>
00151 
00152       typedef
00153       value_type_traits_<
00154     typename my_base::key_type,
00155     typename my_base_data_type::key_type,
00156     typename my_base_data_type::data_type,
00157     typename my_base::allocator>
00158       value_type_traits_t;
00159 
00160       enum
00161     {
00162       has_data =
00163       !is_same_type<
00164       typename my_base_data_type::data_type,
00165       null_data_type>::value
00166     };
00167 
00168     public:
00169 
00170       typedef typename Allocator::size_type size_type;
00171 
00172       typedef typename Allocator::difference_type difference_type;
00173 
00174       typedef typename my_base::allocator allocator;
00175 
00176       typedef typename it_value_type_traits_t::key_type it_key_type;
00177 
00178       typedef
00179       std::pair<
00180     typename my_base::key_type,
00181     typename my_base_data_type::key_type>
00182       key_type;
00183 
00184       typedef
00185       typename allocator::template rebind<
00186     key_type>::other::reference
00187       key_reference;
00188 
00189       typedef
00190       typename allocator::template rebind<
00191     key_type>::other::const_reference
00192       const_key_reference;
00193 
00194       typedef
00195       typename allocator::template rebind<
00196     key_type>::other::pointer
00197       key_pointer;
00198 
00199       typedef
00200       typename allocator::template rebind<
00201     key_type>::other::const_pointer
00202       const_key_pointer;
00203 
00204       typedef typename my_base_data_type::data_type data_type;
00205 
00206       typedef
00207       typename allocator::template rebind<
00208     data_type>::other::reference
00209       data_reference;
00210 
00211       typedef
00212       typename allocator::template rebind<
00213     data_type>::other::const_reference
00214       const_data_reference;
00215 
00216       typedef
00217       typename allocator::template rebind<
00218     data_type>::other::pointer
00219       data_pointer;
00220 
00221       typedef
00222       typename allocator::template rebind<
00223     data_type>::other::const_pointer
00224       const_data_pointer;
00225 
00226       typedef typename value_type_traits_t::value_type value_type;
00227 
00228       typedef typename value_type_traits_t::reference reference;
00229 
00230       typedef typename value_type_traits_t::const_reference const_reference;
00231 
00232       typedef typename value_type_traits_t::pointer pointer;
00233 
00234       typedef typename value_type_traits_t::const_pointer const_pointer;
00235 
00236       typedef
00237       it_<
00238     typename my_base::const_find_iterator,
00239     typename my_base_data_type::const_find_iterator,
00240     has_data,
00241     true>
00242       const_find_iterator;
00243 
00244       typedef
00245       it_<
00246     typename my_base::find_iterator,
00247     typename my_base_data_type::find_iterator,
00248     has_data,
00249     false>
00250       find_iterator;
00251 
00252       typedef
00253       it_<
00254     typename my_base::const_iterator,
00255     typename my_base_data_type::const_iterator,
00256     has_data,
00257     true>
00258       const_iterator;
00259 
00260       typedef
00261       it_<
00262     typename my_base::iterator,
00263     typename my_base_data_type::iterator,
00264     has_data,
00265     false>
00266       iterator;
00267 
00268       enum
00269     {
00270       mapping_level = mapping_level_imp<
00271       typename my_base::given_data_type>::value -1
00272     };
00273 
00274       // Tmp Ami rebind
00275 
00276       typedef compound_ds_tag ds_category;
00277 
00278       typedef
00279       typename cond_type<
00280     mapping_level == 1,
00281     typename cond_type<
00282     has_data,
00283     data_enabled_ms_tag,
00284     basic_ms_tag>::type,
00285     compound_data_enabled_ms_tag>::type
00286       ms_category;
00287 
00288       typedef
00289       typename cond_type<
00290     Mapping_Level == 1,
00291     DS_Tag,
00292     compound_ds_tag>::type
00293       effective_base_ds_tag;
00294 
00295       typedef ds_traits< my_base_data_type> base_data_ds_traits;
00296 
00297       enum
00298     {
00299       erase_can_throw =
00300       base_data_ds_traits::erase_can_throw
00301     };
00302 
00303       enum
00304     {
00305       order_preserving =
00306       order_preserving_imp<
00307       my_base,
00308       effective_base_ds_tag>::value&& 
00309       base_data_ds_traits::order_preserving
00310     };
00311 
00312       enum
00313     {
00314       erase_iterators =
00315       base_data_ds_traits::erase_iterators
00316     };
00317 
00318       typedef
00319       typename ig_sel<
00320     typename invalidation_guarantee_imp<
00321     my_base,
00322     effective_base_ds_tag>::type,
00323     typename ds_traits<
00324     my_base_data_type>::invalidation_guarantee>::type
00325       invalidation_guarantee;
00326 
00327       enum
00328     {
00329       reverse_iteration =
00330       reverse_iteration_imp<
00331       my_base,
00332       effective_base_ds_tag>::value&& 
00333       base_data_ds_traits::reverse_iteration
00334     };
00335 
00336       enum
00337     {
00338       split_join = false
00339     };
00340 
00341     protected:
00342       typedef typename my_base_data_type::data_pointer erase_imp_ret_t;
00343 
00344     private:
00345       inline const_key_reference
00346       extract_key_imp(const_reference r_val, int_to_type<true>)
00347       {
00348     return (r_val.first);
00349       }
00350 
00351       inline const_key_reference
00352       extract_key_imp(const_reference r_val, int_to_type<false>)
00353       {
00354     return (r_val);
00355       }
00356 
00357       inline it_key_type
00358       extract_key_imp(typename iterator::const_reference r_val, int_to_type<true>)
00359       {
00360     return (r_val.first);
00361       }
00362 
00363       inline it_key_type
00364       extract_key_imp(typename iterator::const_reference r_val, int_to_type<false>)
00365       {
00366     return (r_val);
00367       }
00368 
00369     public:
00370 
00371       inline size_type
00372       size() const
00373       {
00374     return (std::distance(begin(), end()));
00375       }
00376 
00377       inline size_type
00378       max_size() const
00379       {
00380     return (my_base::max_size());
00381       }
00382 
00383       inline bool
00384       empty() const
00385       {
00386     return (size() == 0);
00387       }
00388 
00389       inline static const_key_reference
00390       extract_key(const_reference r_val)
00391       {
00392     return (extract_key_imp(
00393                 r_val,
00394                 int_to_type<has_data>()));
00395       }
00396 
00397       inline it_key_type
00398       extract_key(typename iterator::const_reference r_val)
00399       {
00400     return (extract_key_imp(
00401                 r_val,
00402                 int_to_type<has_data>()));
00403       }
00404 
00405       inline std::pair<
00406     find_iterator,
00407     bool>
00408       insert(const_reference r_val)
00409       {
00410     typedef std::pair< typename my_base::find_iterator, bool> base_ins_ret;
00411 
00412     // Tmp Ami
00413       }
00414 
00415       inline data_reference
00416       operator[](const_key_reference r_key)
00417       {
00418     return (subscript_imp(r_key));
00419       }
00420 
00421       inline const_find_iterator
00422       find(const_key_reference r_key) const
00423       {
00424     typename my_base::const_find_iterator it = my_base::find(r_key.first);
00425 
00426     if (it == my_base::end())
00427       return (end());
00428 
00429     typename my_base_data_type::const_find_iterator sec_it =
00430       it->second.find(r_key.second);
00431 
00432     if (sec_it == it->second.end())
00433       return (end());
00434 
00435     return (const_find_iterator(it, sec_it));
00436       }
00437 
00438       inline find_iterator
00439       find(const_key_reference r_key)
00440       {
00441     typename my_base::find_iterator it = my_base::find(r_key.first);
00442 
00443     if (it == my_base::end())
00444       return (end());
00445 
00446     typename my_base_data_type::find_iterator sec_it =
00447       it->second.find(r_key.second);
00448 
00449     if (sec_it == it->second.end())
00450       return (end());
00451 
00452     return (find_iterator(it, my_base::end(), sec_it));
00453       }
00454 
00455       inline const_data_reference
00456       operator[](const_key_reference r_key) const
00457       {
00458     return (my_base::operator[](r_key.first).operator[](r_key.second));
00459       }
00460 
00461       inline size_type
00462       erase(const_key_reference r_key)
00463       {
00464     typename my_base::find_iterator it =
00465       my_base::find(r_key.first);
00466 
00467     if (it == my_base::end())
00468       return (0);
00469 
00470     if (it->second.find(r_key.second) == it->second.end())
00471       return (0);
00472 
00473     it->second.erase(r_key.second);
00474 
00475     return (1);
00476       }
00477 
00478 #include <ext/pb_assoc/detail/value_type_adapter/erase_if_pred.hpp>
00479 
00480       template<class Pred>
00481       inline size_type
00482       erase_if(Pred prd)
00483       {
00484     typename my_base::iterator it = my_base::begin();
00485 
00486     typename my_base::iterator end_it = my_base::end();
00487 
00488     size_type ersd = 0;
00489 
00490     // Tmp Ami check erase can throw
00491 
00492     while (it != end_it)
00493       {
00494         if (it->second.empty() == false)
00495           {
00496         erase_if_pred<Pred> p(prd, it);
00497 
00498         ersd += it->second.erase_if(p);
00499           }
00500 
00501         ++it;
00502       }
00503 
00504     return (ersd);
00505       }
00506 
00507       void
00508       clear()
00509       {
00510     typename my_base::iterator it = my_base::begin();
00511 
00512     typename my_base::iterator end_it = my_base::end();
00513 
00514     while (it != end_it)
00515       it->second.clear();
00516       }
00517 
00518       inline const_iterator
00519       begin() const
00520       {
00521     typename my_base::const_iterator it = my_base::begin();
00522 
00523     while (it != my_base::end()&&  it->second.size() == 0)
00524       ++it;
00525 
00526     if (it == my_base::end())
00527       return (end());
00528 
00529     return (const_iterator(it, my_base::end(), it->second.begin()));
00530       }
00531 
00532       inline iterator
00533       begin()
00534       {
00535     typename my_base::iterator it = my_base::begin();
00536 
00537     while (it != my_base::end()&&  it->second.size() == 0)
00538       ++it;
00539 
00540     if (it == my_base::end())
00541       return (end());
00542 
00543     return (iterator(it, my_base::end(), it->second.begin()));
00544       }
00545 
00546       inline const_iterator
00547       end() const
00548       {
00549     return (const_iterator(my_base::end(), my_base::end()));
00550       }
00551 
00552       inline iterator
00553       end()
00554       {
00555     return (iterator(my_base::end(), my_base::end()));
00556       }
00557 
00558     protected:
00559 
00560       virtual
00561       ~value_type_adapter()
00562       { }
00563 
00564 #define PB_ASSOC_CLASS_NAME value_type_adapter
00565 
00566 #define PB_ASSOC_DIRECT_BASE_C_DEC PB_ASSOC_BASE_C_DEC
00567 
00568 #define PB_ASSOC_DIRECT_BASE_CAST_C_DEC \
00569     typename PB_ASSOC_DIRECT_BASE_C_DEC
00570 
00571 #include <ext/pb_assoc/detail/constructors_destructor_fn_imps.hpp>
00572 
00573 #undef PB_ASSOC_CLASS_NAME
00574 
00575 #undef PB_ASSOC_DIRECT_BASE_C_DEC
00576 
00577 #undef PB_ASSOC_DIRECT_BASE_CAST_C_DEC
00578 
00579       data_reference
00580       subscript_imp(const_key_reference r_key)
00581       {
00582     return (my_base::subscript_imp(r_key.first)[r_key.second]);
00583       }
00584 
00585     private:
00586       value_type_adapter& 
00587       operator=(const value_type_adapter& r_other);
00588     };
00589 
00590 #undef PB_ASSOC_CLASS_T_DEC
00591 
00592 #undef PB_ASSOC_CLASS_C_DEC
00593 
00594 #undef PB_ASSOC_BASE_C_DEC
00595 
00596   } // namespace detail
00597 
00598 } // namespace pb_assoc
00599 
00600 #endif // #ifndef VALUE_TYPE_ADAPTER_HPP
00601 

Generated on Tue Feb 2 16:56:59 2010 for GNU C++ STL by  doxygen 1.4.7