Home | History | Annotate | Download | only in bits
      1 // Pointer Traits -*- C++ -*-
      2 
      3 // Copyright (C) 2011-2013 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file bits/ptr_traits.h
     26  *  This is an internal header file, included by other library headers.
     27  *  Do not attempt to use it directly. @headername{memory}
     28  */
     29 
     30 #ifndef _PTR_TRAITS_H
     31 #define _PTR_TRAITS_H 1
     32 
     33 #if __cplusplus >= 201103L
     34 
     35 #include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
     36 
     37 namespace std _GLIBCXX_VISIBILITY(default)
     38 {
     39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     40 
     41 _GLIBCXX_HAS_NESTED_TYPE(element_type)
     42 _GLIBCXX_HAS_NESTED_TYPE(difference_type)
     43 
     44   template<typename _Tp, bool = __has_element_type<_Tp>::value>
     45     struct __ptrtr_elt_type;
     46 
     47   template<typename _Tp>
     48     struct __ptrtr_elt_type<_Tp, true>
     49     {
     50       typedef typename _Tp::element_type __type;
     51     };
     52 
     53   template<template<typename, typename...> class _SomePtr, typename _Tp,
     54             typename... _Args>
     55     struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false>
     56     {
     57       typedef _Tp __type;
     58     };
     59 
     60   template<typename _Tp, bool = __has_difference_type<_Tp>::value>
     61     struct __ptrtr_diff_type
     62     {
     63       typedef typename _Tp::difference_type __type;
     64     };
     65 
     66   template<typename _Tp>
     67     struct __ptrtr_diff_type<_Tp, false>
     68     {
     69       typedef ptrdiff_t __type;
     70     };
     71 
     72   template<typename _Ptr, typename _Up>
     73     class __ptrtr_rebind_helper
     74     {
     75       template<typename _Ptr2, typename _Up2>
     76 	static constexpr bool
     77        	_S_chk(typename _Ptr2::template rebind<_Up2>*)
     78        	{ return true; }
     79 
     80       template<typename, typename>
     81         static constexpr bool
     82        	_S_chk(...)
     83        	{ return false; }
     84 
     85     public:
     86       static const bool __value = _S_chk<_Ptr, _Up>(nullptr);
     87     };
     88 
     89   template<typename _Ptr, typename _Up>
     90     const bool __ptrtr_rebind_helper<_Ptr, _Up>::__value;
     91 
     92   template<typename _Tp, typename _Up,
     93            bool = __ptrtr_rebind_helper<_Tp, _Up>::__value>
     94     struct __ptrtr_rebind;
     95 
     96   template<typename _Tp, typename _Up>
     97     struct __ptrtr_rebind<_Tp, _Up, true>
     98     {
     99       typedef typename _Tp::template rebind<_Up> __type;
    100     };
    101 
    102   template<template<typename, typename...> class _SomePtr, typename _Up,
    103             typename _Tp, typename... _Args>
    104     struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false>
    105     {
    106       typedef _SomePtr<_Up, _Args...> __type;
    107     };
    108 
    109   template<typename _Tp, typename = typename remove_cv<_Tp>::type>
    110     struct __ptrtr_not_void
    111     {
    112       typedef _Tp __type;
    113     };
    114 
    115   template<typename _Tp>
    116     struct __ptrtr_not_void<_Tp, void>
    117     {
    118       struct __type { };
    119     };
    120 
    121   template<typename _Ptr>
    122     class __ptrtr_pointer_to
    123     {
    124       typedef typename __ptrtr_elt_type<_Ptr>::__type   __orig_type;
    125       typedef typename __ptrtr_not_void<__orig_type>::__type __element_type;
    126 
    127     public:
    128       static _Ptr pointer_to(__element_type& __e)
    129       { return _Ptr::pointer_to(__e); }
    130     };
    131 
    132   /**
    133    * @brief  Uniform interface to all pointer-like types
    134    * @ingroup pointer_abstractions
    135   */
    136   template<typename _Ptr>
    137     struct pointer_traits : __ptrtr_pointer_to<_Ptr>
    138     {
    139       /// The pointer type
    140       typedef _Ptr                                      pointer;
    141       /// The type pointed to
    142       typedef typename __ptrtr_elt_type<_Ptr>::__type   element_type;
    143       /// Type used to represent the difference between two pointers
    144       typedef typename __ptrtr_diff_type<_Ptr>::__type  difference_type;
    145 
    146       template<typename _Up>
    147         using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type;
    148     };
    149 
    150   /**
    151    * @brief  Partial specialization for built-in pointers.
    152    * @ingroup pointer_abstractions
    153   */
    154   template<typename _Tp>
    155     struct pointer_traits<_Tp*>
    156     {
    157       /// The pointer type
    158       typedef _Tp* pointer;
    159       /// The type pointed to
    160       typedef _Tp  element_type;
    161       /// Type used to represent the difference between two pointers
    162       typedef ptrdiff_t difference_type;
    163 
    164       template<typename _Up>
    165         using rebind = _Up*;
    166 
    167       /**
    168        *  @brief  Obtain a pointer to an object
    169        *  @param  __r  A reference to an object of type @c element_type
    170        *  @return @c addressof(__r)
    171       */
    172       static pointer
    173       pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) noexcept
    174       { return std::addressof(__r); }
    175     };
    176 
    177 _GLIBCXX_END_NAMESPACE_VERSION
    178 } // namespace std
    179 
    180 #endif
    181 
    182 #endif
    183