libstdc++
types_traits.hpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2009, 2011 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 terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00026 
00027 // Permission to use, copy, modify, sell, and distribute this software
00028 // is hereby granted without fee, provided that the above copyright
00029 // notice appears in all copies, and that both that copyright notice
00030 // and this permission notice appear in supporting documentation. None
00031 // of the above authors, nor IBM Haifa Research Laboratories, make any
00032 // representation about the suitability of this software for any
00033 // purpose. It is provided "as is" without express or implied
00034 // warranty.
00035 
00036 /**
00037  * @file detail/types_traits.hpp
00038  * Contains a traits class of types used by containers.
00039  */
00040 
00041 #ifndef PB_DS_TYPES_TRAITS_HPP
00042 #define PB_DS_TYPES_TRAITS_HPP
00043 
00044 #include <algorithm>
00045 #include <utility>
00046 #include <ext/pb_ds/tag_and_trait.hpp>
00047 #include <ext/pb_ds/detail/type_utils.hpp>
00048 #include <utility>
00049 
00050 namespace __gnu_pbds
00051 {
00052   namespace detail
00053   {
00054     /**
00055      *  @addtogroup traits Traits
00056      *  @{
00057      */
00058 
00059     /// Primary template.
00060     template<typename Key, typename Mapped>
00061       struct no_throw_copies
00062       {
00063     static const bool __simple = is_simple<Key>::value
00064                  && is_simple<Mapped>::value;
00065     typedef integral_constant<int, __simple>            indicator;
00066       };
00067 
00068     /// Specialization.
00069     template<typename Key>
00070       struct no_throw_copies<Key, null_type>
00071       {
00072     typedef integral_constant<int, is_simple<Key>::value>   indicator;
00073       };
00074 
00075 
00076     /// Stored value.
00077     template<typename _Tv>
00078       struct stored_value
00079       {
00080     typedef _Tv     value_type;
00081     value_type  m_value;
00082       };
00083 
00084     /// Stored hash.
00085     template<typename _Th>
00086       struct stored_hash
00087       {
00088     typedef _Th     hash_type;
00089     hash_type   m_hash;
00090       };
00091 
00092     /// Primary template for representation of stored data.
00093     /// Two types of data can be stored: value and hash.
00094     template<typename _Tv, typename _Th>
00095       struct stored_data
00096       : public stored_value<_Tv>, public stored_hash<_Th>
00097       { };
00098 
00099     /// Specialization for representation of stored data of just value type.
00100     template<typename _Tv>
00101       struct stored_data<_Tv, null_type>
00102       : public stored_value<_Tv>
00103       { };
00104 
00105     /// Primary template.
00106     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
00107       struct type_base;
00108 
00109     /**
00110      * Specialization of type_base for the case where the hash value
00111      * is not stored alongside each value.
00112      */
00113     template<typename Key, typename Mapped, typename _Alloc>
00114       struct type_base<Key, Mapped, _Alloc, false>
00115       {
00116       public:
00117     typedef typename _Alloc::size_type      size_type;
00118 
00119       private:
00120     typedef typename _Alloc::template rebind<Mapped>    __rebind_m;
00121     typedef typename __rebind_m::other          __rebind_ma;
00122     typedef std::pair<const Key, Mapped>            __value_type;
00123     typedef typename _Alloc::template rebind<__value_type>  __rebind_v;
00124         typedef typename __rebind_v::other          __rebind_va;
00125 
00126       public:
00127     typedef typename __rebind_ma::value_type        mapped_type;
00128     typedef typename __rebind_ma::pointer       mapped_pointer;
00129     typedef typename __rebind_ma::const_pointer     mapped_const_pointer;
00130     typedef typename __rebind_ma::reference         mapped_reference;
00131     typedef typename __rebind_ma::const_reference   mapped_const_reference;
00132 
00133     typedef typename __rebind_va::value_type    value_type;
00134     typedef typename __rebind_va::pointer       pointer;
00135     typedef typename __rebind_va::const_pointer     const_pointer;
00136     typedef typename __rebind_va::reference     reference;
00137     typedef typename __rebind_va::const_reference   const_reference;
00138 
00139     typedef stored_data<value_type, null_type>  stored_data_type;
00140       };
00141 
00142     /**
00143      * Specialization of type_base for the case where the hash value
00144      * is stored alongside each value.
00145      */
00146     template<typename Key, typename Mapped, typename _Alloc>
00147       struct type_base<Key, Mapped, _Alloc, true>
00148       {
00149       public:
00150     typedef typename _Alloc::size_type      size_type;
00151 
00152       private:
00153     typedef typename _Alloc::template rebind<Mapped>    __rebind_m;
00154     typedef typename __rebind_m::other          __rebind_ma;
00155     typedef std::pair<const Key, Mapped>            __value_type;
00156     typedef typename _Alloc::template rebind<__value_type>  __rebind_v;
00157         typedef typename __rebind_v::other          __rebind_va;
00158 
00159       public:
00160     typedef typename __rebind_ma::value_type        mapped_type;
00161     typedef typename __rebind_ma::pointer       mapped_pointer;
00162     typedef typename __rebind_ma::const_pointer     mapped_const_pointer;
00163     typedef typename __rebind_ma::reference         mapped_reference;
00164     typedef typename __rebind_ma::const_reference   mapped_const_reference;
00165 
00166     typedef typename __rebind_va::value_type    value_type;
00167     typedef typename __rebind_va::pointer       pointer;
00168     typedef typename __rebind_va::const_pointer     const_pointer;
00169     typedef typename __rebind_va::reference     reference;
00170     typedef typename __rebind_va::const_reference   const_reference;
00171 
00172     typedef stored_data<value_type, size_type>  stored_data_type;
00173       };
00174 
00175 
00176     /**
00177      * Specialization of type_base for the case where the hash value
00178      * is not stored alongside each value.
00179      */
00180     template<typename Key, typename _Alloc>
00181       struct type_base<Key, null_type, _Alloc, false>
00182       {
00183       public:
00184     typedef typename _Alloc::size_type      size_type;
00185     typedef Key                     value_type;
00186 
00187       private:
00188     typedef typename _Alloc::template rebind<null_type>     __rebind_m;
00189     typedef typename __rebind_m::other          __rebind_ma;
00190     typedef typename _Alloc::template rebind<value_type>    __rebind_v;
00191         typedef typename __rebind_v::other          __rebind_va;
00192 
00193       public:
00194     typedef typename __rebind_ma::value_type        mapped_type;
00195     typedef typename __rebind_ma::pointer       mapped_pointer;
00196     typedef typename __rebind_ma::const_pointer     mapped_const_pointer;
00197     typedef typename __rebind_ma::reference         mapped_reference;
00198     typedef typename __rebind_ma::const_reference   mapped_const_reference;
00199 
00200     typedef typename __rebind_va::pointer       pointer;
00201     typedef typename __rebind_va::const_pointer     const_pointer;
00202     typedef typename __rebind_va::reference     reference;
00203     typedef typename __rebind_va::const_reference   const_reference;
00204 
00205     typedef stored_data<value_type, null_type>  stored_data_type;
00206 
00207     static null_type            s_null_type;
00208       };
00209 
00210     template<typename Key, typename _Alloc>
00211       null_type
00212       type_base<Key, null_type, _Alloc, false>::s_null_type;
00213 
00214 
00215     /**
00216      * Specialization of type_base for the case where the hash value
00217      * is stored alongside each value.
00218      */
00219     template<typename Key, typename _Alloc>
00220       struct type_base<Key, null_type, _Alloc, true>
00221       {
00222       public:
00223     typedef typename _Alloc::size_type      size_type;
00224     typedef Key                     value_type;
00225 
00226       private:
00227     typedef typename _Alloc::template rebind<null_type>     __rebind_m;
00228     typedef typename __rebind_m::other          __rebind_ma;
00229     typedef typename _Alloc::template rebind<value_type>    __rebind_v;
00230         typedef typename __rebind_v::other          __rebind_va;
00231 
00232       public:
00233     typedef typename __rebind_ma::value_type        mapped_type;
00234     typedef typename __rebind_ma::pointer       mapped_pointer;
00235     typedef typename __rebind_ma::const_pointer     mapped_const_pointer;
00236     typedef typename __rebind_ma::reference         mapped_reference;
00237     typedef typename __rebind_ma::const_reference   mapped_const_reference;
00238 
00239     typedef typename __rebind_va::pointer       pointer;
00240     typedef typename __rebind_va::const_pointer     const_pointer;
00241     typedef typename __rebind_va::reference     reference;
00242     typedef typename __rebind_va::const_reference   const_reference;
00243 
00244     typedef stored_data<value_type, size_type>  stored_data_type;
00245 
00246     static null_type                s_null_type;
00247       };
00248 
00249     template<typename Key, typename _Alloc>
00250       null_type
00251       type_base<Key, null_type, _Alloc, true>::s_null_type;
00252 
00253 
00254     /// Type base dispatch.
00255     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
00256       struct type_dispatch
00257       {
00258     typedef type_base<Key, Mapped, _Alloc, Store_Hash> type;
00259       };
00260 
00261     /// Traits for abstract types.
00262     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
00263       struct types_traits
00264       : public type_dispatch<Key, Mapped, _Alloc, Store_Hash>::type
00265       {
00266       private:
00267     typedef no_throw_copies<Key, Mapped>        __nothrowcopy;
00268     typedef typename _Alloc::template rebind<Key>::other __rebind_a;
00269 
00270       public:
00271     typedef typename _Alloc::size_type      size_type;
00272     typedef typename __rebind_a::value_type     key_type;
00273     typedef typename __rebind_a::pointer        key_pointer;
00274     typedef typename __rebind_a::const_pointer  key_const_pointer;
00275     typedef typename __rebind_a::reference      key_reference;
00276     typedef typename __rebind_a::const_reference    key_const_reference;
00277     typedef std::pair<size_type, size_type>     comp_hash;
00278     typedef integral_constant<int, Store_Hash>  store_extra;
00279     typedef typename __nothrowcopy::indicator   no_throw_indicator;
00280 
00281     store_extra                 m_store_extra_indicator;
00282     no_throw_indicator          m_no_throw_copies_indicator;
00283     };
00284     //@}
00285   } // namespace detail
00286 } // namespace __gnu_pbds
00287 
00288 #endif