Changeset 537b300 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:23Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e13c378
Parents:
3c32c48
git-author:
Dzejrou <dzejrou@…> (2018-05-08 23:49:46)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:23)
Message:

cpp: added more definitions to shared_ptr and a WIP version of shared_payload

Location:
uspace/lib/cpp/include/internal/memory
Files:
1 added
1 edited

Legend:

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

    r3c32c48 r537b300  
    3131
    3232#include <exception>
     33#include <functional>
     34#include <type_traits>
    3335
    3436namespace std
     
    147149             */
    148150
    149             element_type* get() const noexcept;
     151            element_type* get() const noexcept
     152            {
     153                if (payload_)
     154                    return payload_->get();
     155                else
     156                    return nullptr;
     157            }
    150158
    151159            T& operator*() const noexcept;
    152160
    153             T* operator->() const noexcept;
    154 
    155             long use_count() const noexcept;
    156 
    157             bool unique() const noexcept;
    158 
    159             explicit operator bool() const noexcept;
    160 
    161             template<class U>
    162             bool owner_before(const shared_ptr<U>& ptr) const;
     161            T* operator->() const noexcept
     162            {
     163                return get();
     164            }
     165
     166            long use_count() const noexcept
     167            {
     168                if (payload_)
     169                    return payload_->refcount();
     170                else
     171                    return 0L;
     172            }
     173
     174            bool unique() const noexcept
     175            {
     176                return use_count() == 1L;
     177            }
     178
     179            explicit operator bool() const noexcept
     180            {
     181                return get() != nullptr;
     182            }
     183
     184            template<class U>
     185            bool owner_before(const shared_ptr<U>& ptr) const
     186            {
     187                return payload_ < ptr.payload_;
     188            }
    163189
    164190            template<class U>
    165191            bool owner_before(const weak_ptr<U>& ptr) const;
    166192
    167         /* private: */
     193        private:
     194            aux::shared_payload<element_type>* payload_;
     195
     196            shared_ptr(aux::shared_payload<element_type>* payload)
     197                : payload_{payload}
     198            { /* DUMMY BODY */ }
     199
     200            template<class U, class... Args>
     201            friend shared_ptr<U> make_shared(Args&&...);
     202
     203            template<class U, class A, class... Args>
     204            friend shared_ptr<U> allocate_shared(const A&, Args&&...);
    168205    };
    169206
    170207    /**
    171208     * 20.8.2.2.6, shared_ptr creation:
     209     * Note: According to the standard, these two functions
     210     *       should perform at most one memory allocation
     211     *       (should, don't have to :P). It might be better
     212     *       to create payloads that embed the type T to
     213     *       perform this optimization.
    172214     */
    173215
    174216    template<class T, class... Args>
    175     shared_ptr<T> make_shared(Args&&... args);
     217    shared_ptr<T> make_shared(Args&&... args)
     218    {
     219        return shared_ptr<T>{
     220            new aux::shared_payload<T>{forward<Args>(args)...}
     221        };
     222    }
    176223
    177224    template<class T, class A, class... Args>
    178     shared_ptr<T> allocate_shared(const A& alloc, Args&&... args);
     225    shared_ptr<T> allocate_shared(const A& alloc, Args&&... args)
     226    {
     227        return shared_ptr<T>{
     228            new aux::shared_payload<T>{A{alloc}, forward<Args>(args)...}
     229        };
     230    }
    179231
    180232    /**
     
    183235
    184236    template<class T, class U>
    185     bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    186 
    187     template<class T, class U>
    188     bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    189 
    190     template<class T, class U>
    191     bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    192 
    193     template<class T, class U>
    194     bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    195 
    196     template<class T, class U>
    197     bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    198 
    199     template<class T, class U>
    200     bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
    201 
    202     template<class T>
    203     bool operator==(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    204 
    205     template<class T>
    206     bool operator==(nullptr_t, const shared_ptr<T>& rhs) noexcept;
    207 
    208     template<class T>
    209     bool operator!=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    210 
    211     template<class T>
    212     bool operator!=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
    213 
    214     template<class T>
    215     bool operator<(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    216 
    217     template<class T>
    218     bool operator<(nullptr_t, const shared_ptr<T>& rhs) noexcept;
    219 
    220     template<class T>
    221     bool operator>(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    222 
    223     template<class T>
    224     bool operator>(nullptr_t, const shared_ptr<T>& rhs) noexcept;
    225 
    226     template<class T>
    227     bool operator<=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    228 
    229     template<class T>
    230     bool operator<=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
    231 
    232     template<class T>
    233     bool operator>=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
    234 
    235     template<class T>
    236     bool operator>=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
     237    bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     238    {
     239        return lhs.get() == rhs.get();
     240    }
     241
     242    template<class T, class U>
     243    bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     244    {
     245        return !(lhs == rhs);
     246    }
     247
     248    template<class T, class U>
     249    bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     250    {
     251        return less<common_type_t<T*, U*>>{}(lhs.get(), rhs.get());
     252    }
     253
     254    template<class T, class U>
     255    bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     256    {
     257        return rhs < lhs;
     258    }
     259
     260    template<class T, class U>
     261    bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     262    {
     263        return !(rhs < lhs);
     264    }
     265
     266    template<class T, class U>
     267    bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
     268    {
     269        return !(lhs < rhs);
     270    }
     271
     272    template<class T>
     273    bool operator==(const shared_ptr<T>& lhs, nullptr_t) noexcept
     274    {
     275        return !lhs;
     276    }
     277
     278    template<class T>
     279    bool operator==(nullptr_t, const shared_ptr<T>& rhs) noexcept
     280    {
     281        return !rhs;
     282    }
     283
     284    template<class T>
     285    bool operator!=(const shared_ptr<T>& lhs, nullptr_t) noexcept
     286    {
     287        return (bool)lhs;
     288    }
     289
     290    template<class T>
     291    bool operator!=(nullptr_t, const shared_ptr<T>& rhs) noexcept
     292    {
     293        return (bool)rhs;
     294    }
     295
     296    template<class T>
     297    bool operator<(const shared_ptr<T>& lhs, nullptr_t) noexcept
     298    {
     299        return less<T*>{}(lhs.get(), nullptr);
     300    }
     301
     302    template<class T>
     303    bool operator<(nullptr_t, const shared_ptr<T>& rhs) noexcept
     304    {
     305        return less<T*>{}(nullptr, rhs.get());
     306    }
     307
     308    template<class T>
     309    bool operator>(const shared_ptr<T>& lhs, nullptr_t) noexcept
     310    {
     311        return nullptr < lhs;
     312    }
     313
     314    template<class T>
     315    bool operator>(nullptr_t, const shared_ptr<T>& rhs) noexcept
     316    {
     317        return rhs < nullptr;
     318    }
     319
     320    template<class T>
     321    bool operator<=(const shared_ptr<T>& lhs, nullptr_t) noexcept
     322    {
     323        return !(nullptr < lhs);
     324    }
     325
     326    template<class T>
     327    bool operator<=(nullptr_t, const shared_ptr<T>& rhs) noexcept
     328    {
     329        return !(rhs < nullptr);
     330    }
     331
     332    template<class T>
     333    bool operator>=(const shared_ptr<T>& lhs, nullptr_t) noexcept
     334    {
     335        return !(lhs < nullptr);
     336    }
     337
     338    template<class T>
     339    bool operator>=(nullptr_t, const shared_ptr<T>& rhs) noexcept
     340    {
     341        return !(nullptr < rhs);
     342    }
    237343
    238344    /**
     
    251357
    252358    template<class T, class U>
    253     shared_ptr<T> static_pointer_cast(const shared_ptr<U>& ptr) noexcept;
    254 
    255     template<class T, class U>
    256     shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& ptr) noexcept;
    257 
    258     template<class T, class U>
    259     shared_ptr<T> const_pointer_cast(const shared_ptr<U>& ptr) noexcept;
     359    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& ptr) noexcept
     360    {
     361        if (!ptr)
     362            return shared_ptr<T>{};
     363
     364        return shared_ptr<T>{
     365            ptr, static_cast<T*>(ptr.get())
     366        };
     367    }
     368
     369    template<class T, class U>
     370    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& ptr) noexcept
     371    {
     372        if (auto res = dynamic_cast<T*>(ptr.get()))
     373            return shared_ptr<T>{ptr, res};
     374        else
     375            return shared_ptr<T>{};
     376    }
     377
     378    template<class T, class U>
     379    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& ptr) noexcept
     380    {
     381        if (!ptr)
     382            return shared_ptr<T>{};
     383
     384        return shared_ptr<T>{
     385            ptr, const_cast<T*>(ptr.get())
     386        };
     387    }
    260388
    261389    /**
     
    264392
    265393    template<class D, class T>
    266     D* get_deleter(const shared_ptr<T>& ptr) noexcept;
     394    D* get_deleter(const shared_ptr<T>& ptr) noexcept
     395    {
     396        // TODO: implement this through payload
     397    }
    267398
    268399    /**
     
    272403    template<class Char, class Traits, class T>
    273404    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
    274                                             const shared_ptr<T>& ptr);
     405                                            const shared_ptr<T>& ptr)
     406    {
     407        return os << ptr.get();
     408    }
    275409}
    276410
Note: See TracChangeset for help on using the changeset viewer.