Ignore:
Timestamp:
2018-07-05T21:41:24Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ca8d393
Parents:
17012fcf
git-author:
Dzejrou <dzejrou@…> (2018-05-16 00:49:54)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:24)
Message:

cpp: moved type getters for allocator and pointer traits to a separate header, fully implemented pointer_traits and added pointer_traits tests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/memory.hpp

    r17012fcf rbfc972e  
    3232#include <internal/aux.hpp>
    3333#include <internal/functional/hash.hpp>
     34#include <internal/memory/addressof.hpp>
    3435#include <internal/memory/allocator_arg.hpp>
    35 #include <internal/memory/addressof.hpp>
     36#include <internal/memory/type_getters.hpp>
    3637#include <iterator>
    3738#include <new>
     
    4344    /**
    4445     * 20.7.3, pointer traits:
     46     * Note: The type getters that are used in pointer_traits
     47     *       and allocator_traits are implemented in
     48     *       <internal/memory/type_getters.hpp>.
    4549     */
    4650
     
    4852    struct pointer_traits
    4953    {
    50         using pointer = Ptr;
    51         // TODO: element type, difference type
    52 
    53         // TODO: this is conditional, see standard
     54        using pointer         = Ptr;
     55        using element_type    = typename aux::ptr_get_element_type<Ptr>::type;
     56        using difference_type = typename aux::ptr_get_difference_type<Ptr>::type;
     57
    5458        template<class U>
    55         using rebind = typename Ptr::template rebind<U>;
     59        using rebind = typename aux::ptr_get_rebind<Ptr, U>::type;
     60
     61        static pointer pointer_to( // If is_void_t<element_type>, this type is unspecified.
     62            conditional_t<is_void_v<element_type>, char, element_type&> x
     63        )
     64        {
     65            return Ptr::pointer_to(x);
     66        }
    5667    };
     68
     69    template<class T>
     70    struct pointer_traits<T*>
     71    {
     72        using pointer         = T*;
     73        using element_type    = T;
     74        using difference_type = ptrdiff_t;
     75
     76        template<class U>
     77        using rebind = U*;
     78
     79        static pointer pointer_to(
     80            conditional_t<is_void_v<element_type>, char, element_type&> x
     81        )
     82        {
     83            return std::addressof(x);
     84        }
     85    };
     86
     87    /**
     88     * 20.7.4, pointer safety:
     89     */
     90
     91    // TODO: implement
     92
     93    /**
     94     * 20.7.5, align:
     95     */
     96
     97    // TODO: implement
    5798
    5899    /**
     
    84125     * 20.7.8, allocator traits:
    85126     */
    86 
    87     namespace aux
    88     {
    89         /**
    90          * The standard mandates that we reuse type from allocators
    91          * *if* they are defined or that we use something different.
    92          * These structures help us alternate between those by
    93          * using SFINAE.
    94          * TODO: Create tests for these!
    95          */
    96 
    97         template<class T, class = void>
    98         struct get_pointer: aux::type_is<typename T::value_type*>
    99         { /* DUMMY BODY */ };
    100 
    101         template<class T>
    102         struct get_pointer<T, void_t<typename T::pointer>>
    103             : aux::type_is<typename T::pointer>
    104         { /* DUMMY BODY */ };
    105 
    106         template<class T, class Ptr, class = void>
    107         struct get_const_pointer
    108             : aux::type_is<typename pointer_traits<Ptr>::template rebind<const typename T::value_type>>
    109         { /* DUMMY BODY */ };
    110 
    111         template<class T, class Ptr>
    112         struct get_const_pointer<T, Ptr, void_t<typename T::const_pointer>>
    113             : aux::type_is<typename T::const_pointer>
    114         { /* DUMMY BODY */ };
    115 
    116         template<class T, class Ptr, class = void>
    117         struct get_void_pointer
    118             : aux::type_is<typename pointer_traits<Ptr>::template rebind<void>>
    119         { /* DUMMY BODY */ };
    120 
    121         template<class T, class Ptr>
    122         struct get_void_pointer<T, Ptr, void_t<typename T::void_pointer>>
    123             : aux::type_is<typename T::void_pointer>
    124         { /* DUMMY BODY */ };
    125 
    126         template<class T, class Ptr, class = void>
    127         struct get_const_void_pointer
    128             : aux::type_is<typename pointer_traits<Ptr>::template rebind<const void>>
    129         { /* DUMMY BODY */ };
    130 
    131         template<class T, class Ptr>
    132         struct get_const_void_pointer<T, Ptr, void_t<typename T::const_void_pointer>>
    133             : aux::type_is<typename T::const_void_pointer>
    134         { /* DUMMY BODY */ };
    135 
    136         template<class T, class Ptr, class = void>
    137         struct get_difference_type
    138             : aux::type_is<typename pointer_traits<Ptr>::difference_type>
    139         { /* DUMMY BODY */ };
    140 
    141         template<class T, class Ptr>
    142         struct get_difference_type<T, Ptr, void_t<typename T::difference_type>>
    143             : aux::type_is<typename T::difference_type>
    144         { /* DUMMY BODY */ };
    145 
    146         template<class T, class Difference, class = void>
    147         struct get_size_type: aux::type_is<make_unsigned_t<Difference>>
    148         { /* DUMMY BODY */ };
    149 
    150         template<class T, class Difference>
    151         struct get_size_type<T, Difference, void_t<typename T::size_type>>
    152             : aux::type_is<typename T::size_type>
    153         { /* DUMMY BODY */ };
    154 
    155         template<class T, class = void>
    156         struct get_copy_propagate: aux::type_is<false_type>
    157         { /* DUMMY BODY */ };
    158 
    159         template<class T>
    160         struct get_copy_propagate<T, void_t<typename T::propagate_on_container_copy_assignment>>
    161             : aux::type_is<typename T::propagate_on_container_copy_assignment>
    162         { /* DUMMY BODY */ };
    163 
    164         template<class T, class = void>
    165         struct get_move_propagate: aux::type_is<false_type>
    166         { /* DUMMY BODY */ };
    167 
    168         template<class T>
    169         struct get_move_propagate<T, void_t<typename T::propagate_on_container_move_assignment>>
    170             : aux::type_is<typename T::propagate_on_container_move_assignment>
    171         { /* DUMMY BODY */ };
    172 
    173         template<class T, class = void>
    174         struct get_swap_propagate: aux::type_is<false_type>
    175         { /* DUMMY BODY */ };
    176 
    177         template<class T>
    178         struct get_swap_propagate<T, void_t<typename T::propagate_on_container_swap>>
    179             : aux::type_is<typename T::propagate_on_container_swap>
    180         { /* DUMMY BODY */ };
    181 
    182         template<class T, class = void>
    183         struct get_always_equal: aux::type_is<typename is_empty<T>::type>
    184         { /* DUMMY BODY */ };
    185 
    186         template<class T>
    187         struct get_always_equal<T, void_t<typename T::is_always_equal>>
    188             : aux::type_is<typename T::is_always_equal>
    189         { /* DUMMY BODY */ };
    190 
    191         template<class Alloc, class T, class = void>
    192         struct get_rebind_other
    193         { /* DUMMY BODY */ };
    194 
    195         template<class Alloc, class T>
    196         struct get_rebind_other<Alloc, T, void_t<typename Alloc::template rebind<T>::other>>
    197             : aux::type_is<typename Alloc::template rebind<T>::other>
    198         { /* DUMMY BODY */ };
    199 
    200         /* TODO: How am I suppose to do this?!
    201         template<template<class T, class... Args> class Alloc>
    202         struct get_rebind_args;
    203         */
    204 
    205         template<class Alloc, class T>
    206         struct get_rebind_args: aux::type_is<typename get_rebind_other<Alloc, T>::type>
    207         { /* DUMMY BODY */ };
    208     }
    209127
    210128    template<class Alloc>
Note: See TracChangeset for help on using the changeset viewer.