xref: /minix3/external/bsd/libc++/dist/libcxx/include/experimental/dynarray (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
14684ddb6SLionel Sambuc// -*- C++ -*-
24684ddb6SLionel Sambuc//===-------------------------- dynarray ----------------------------------===//
34684ddb6SLionel Sambuc//
44684ddb6SLionel Sambuc//                     The LLVM Compiler Infrastructure
54684ddb6SLionel Sambuc//
64684ddb6SLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open
74684ddb6SLionel Sambuc// Source Licenses. See LICENSE.TXT for details.
84684ddb6SLionel Sambuc//
94684ddb6SLionel Sambuc//===----------------------------------------------------------------------===//
104684ddb6SLionel Sambuc
114684ddb6SLionel Sambuc#ifndef _LIBCPP_DYNARRAY
124684ddb6SLionel Sambuc#define _LIBCPP_DYNARRAY
134684ddb6SLionel Sambuc
144684ddb6SLionel Sambuc#include <__config>
154684ddb6SLionel Sambuc#if _LIBCPP_STD_VER > 11
164684ddb6SLionel Sambuc
174684ddb6SLionel Sambuc/*
184684ddb6SLionel Sambuc    dynarray synopsis
194684ddb6SLionel Sambuc
204684ddb6SLionel Sambucnamespace std { namespace experimental {
214684ddb6SLionel Sambuc
224684ddb6SLionel Sambuctemplate< typename T >
234684ddb6SLionel Sambucclass dynarray
244684ddb6SLionel Sambuc{
254684ddb6SLionel Sambuc    // types:
264684ddb6SLionel Sambuc    typedef       T                               value_type;
274684ddb6SLionel Sambuc    typedef       T&                              reference;
284684ddb6SLionel Sambuc    typedef const T&                              const_reference;
294684ddb6SLionel Sambuc    typedef       T*                              pointer;
304684ddb6SLionel Sambuc    typedef const T*                              const_pointer;
314684ddb6SLionel Sambuc    typedef       implementation-defined          iterator;
324684ddb6SLionel Sambuc    typedef       implementation-defined          const_iterator;
334684ddb6SLionel Sambuc    typedef reverse_iterator<iterator>            reverse_iterator;
344684ddb6SLionel Sambuc    typedef reverse_iterator<const_iterator>      const_reverse_iterator;
354684ddb6SLionel Sambuc    typedef size_t                                size_type;
364684ddb6SLionel Sambuc    typedef ptrdiff_t                             difference_type;
374684ddb6SLionel Sambuc
384684ddb6SLionel Sambucpublic:
394684ddb6SLionel Sambuc    // construct/copy/destroy:
404684ddb6SLionel Sambuc    explicit dynarray(size_type c);
414684ddb6SLionel Sambuc    dynarray(size_type c, const T& v);
424684ddb6SLionel Sambuc    dynarray(const dynarray& d);
434684ddb6SLionel Sambuc    dynarray(initializer_list<T>);
444684ddb6SLionel Sambuc
45*0a6a1f1dSLionel Sambuc    template <class Alloc>
46*0a6a1f1dSLionel Sambuc      dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
47*0a6a1f1dSLionel Sambuc    template <class Alloc>
48*0a6a1f1dSLionel Sambuc      dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
49*0a6a1f1dSLionel Sambuc    template <class Alloc>
50*0a6a1f1dSLionel Sambuc      dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
51*0a6a1f1dSLionel Sambuc    template <class Alloc>
52*0a6a1f1dSLionel Sambuc      dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
534684ddb6SLionel Sambuc    dynarray& operator=(const dynarray&) = delete;
544684ddb6SLionel Sambuc    ~dynarray();
554684ddb6SLionel Sambuc
564684ddb6SLionel Sambuc    // iterators:
574684ddb6SLionel Sambuc    iterator       begin()        noexcept;
584684ddb6SLionel Sambuc    const_iterator begin()  const noexcept;
594684ddb6SLionel Sambuc    const_iterator cbegin() const noexcept;
604684ddb6SLionel Sambuc    iterator       end()          noexcept;
614684ddb6SLionel Sambuc    const_iterator end()    const noexcept;
624684ddb6SLionel Sambuc    const_iterator cend()   const noexcept;
634684ddb6SLionel Sambuc
644684ddb6SLionel Sambuc    reverse_iterator       rbegin()        noexcept;
654684ddb6SLionel Sambuc    const_reverse_iterator rbegin()  const noexcept;
664684ddb6SLionel Sambuc    const_reverse_iterator crbegin() const noexcept;
674684ddb6SLionel Sambuc    reverse_iterator       rend()          noexcept;
684684ddb6SLionel Sambuc    const_reverse_iterator rend()    const noexcept;
694684ddb6SLionel Sambuc    const_reverse_iterator crend()   const noexcept;
704684ddb6SLionel Sambuc
714684ddb6SLionel Sambuc    // capacity:
724684ddb6SLionel Sambuc    size_type size()     const noexcept;
734684ddb6SLionel Sambuc    size_type max_size() const noexcept;
744684ddb6SLionel Sambuc    bool      empty()    const noexcept;
754684ddb6SLionel Sambuc
764684ddb6SLionel Sambuc    // element access:
774684ddb6SLionel Sambuc    reference       operator[](size_type n);
784684ddb6SLionel Sambuc    const_reference operator[](size_type n) const;
794684ddb6SLionel Sambuc
804684ddb6SLionel Sambuc    reference       front();
814684ddb6SLionel Sambuc    const_reference front() const;
824684ddb6SLionel Sambuc    reference       back();
834684ddb6SLionel Sambuc    const_reference back()  const;
844684ddb6SLionel Sambuc
854684ddb6SLionel Sambuc    const_reference at(size_type n) const;
864684ddb6SLionel Sambuc    reference       at(size_type n);
874684ddb6SLionel Sambuc
884684ddb6SLionel Sambuc    // data access:
894684ddb6SLionel Sambuc    T*       data()       noexcept;
904684ddb6SLionel Sambuc    const T* data() const noexcept;
914684ddb6SLionel Sambuc
924684ddb6SLionel Sambuc    // mutating member functions:
934684ddb6SLionel Sambuc    void fill(const T& v);
944684ddb6SLionel Sambuc};
954684ddb6SLionel Sambuc
964684ddb6SLionel Sambuc}}  // std::experimental
974684ddb6SLionel Sambuc
984684ddb6SLionel Sambuc*/
994684ddb6SLionel Sambuc
1004684ddb6SLionel Sambuc#include <__functional_base>
1014684ddb6SLionel Sambuc#include <iterator>
1024684ddb6SLionel Sambuc#include <stdexcept>
1034684ddb6SLionel Sambuc#include <initializer_list>
1044684ddb6SLionel Sambuc#include <new>
1054684ddb6SLionel Sambuc#include <algorithm>
1064684ddb6SLionel Sambuc
107*0a6a1f1dSLionel Sambuc#include <__undef___deallocate>
108*0a6a1f1dSLionel Sambuc
1094684ddb6SLionel Sambuc#if defined(_LIBCPP_NO_EXCEPTIONS)
1104684ddb6SLionel Sambuc    #include <cassert>
1114684ddb6SLionel Sambuc#endif
1124684ddb6SLionel Sambuc
1134684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1144684ddb6SLionel Sambuc#pragma GCC system_header
1154684ddb6SLionel Sambuc#endif
1164684ddb6SLionel Sambuc
1174684ddb6SLionel Sambucnamespace std { namespace experimental { inline namespace __array_extensions_v1 {
1184684ddb6SLionel Sambuc
1194684ddb6SLionel Sambuctemplate <class _Tp>
1204684ddb6SLionel Sambucstruct _LIBCPP_TYPE_VIS_ONLY dynarray
1214684ddb6SLionel Sambuc{
1224684ddb6SLionel Sambucpublic:
1234684ddb6SLionel Sambuc    // types:
1244684ddb6SLionel Sambuc    typedef dynarray __self;
1254684ddb6SLionel Sambuc    typedef _Tp                                   value_type;
1264684ddb6SLionel Sambuc    typedef value_type&                           reference;
1274684ddb6SLionel Sambuc    typedef const value_type&                     const_reference;
1284684ddb6SLionel Sambuc    typedef value_type*                           iterator;
1294684ddb6SLionel Sambuc    typedef const value_type*                     const_iterator;
1304684ddb6SLionel Sambuc    typedef value_type*                           pointer;
1314684ddb6SLionel Sambuc    typedef const value_type*                     const_pointer;
1324684ddb6SLionel Sambuc    typedef size_t                                size_type;
1334684ddb6SLionel Sambuc    typedef ptrdiff_t                             difference_type;
1344684ddb6SLionel Sambuc    typedef std::reverse_iterator<iterator>       reverse_iterator;
1354684ddb6SLionel Sambuc    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1364684ddb6SLionel Sambuc
1374684ddb6SLionel Sambucprivate:
1384684ddb6SLionel Sambuc    size_t                  __size_;
1394684ddb6SLionel Sambuc    value_type *            __base_;
1404684ddb6SLionel Sambuc    _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {}
1414684ddb6SLionel Sambuc
1424684ddb6SLionel Sambuc    static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
1434684ddb6SLionel Sambuc    {
1444684ddb6SLionel Sambuc        if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )
1454684ddb6SLionel Sambuc        {
1464684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
1474684ddb6SLionel Sambuc            throw bad_array_length();
1484684ddb6SLionel Sambuc#else
1494684ddb6SLionel Sambuc            assert(!"dynarray::allocation");
1504684ddb6SLionel Sambuc#endif
1514684ddb6SLionel Sambuc        }
152*0a6a1f1dSLionel Sambuc        return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count));
1534684ddb6SLionel Sambuc    }
1544684ddb6SLionel Sambuc
1554684ddb6SLionel Sambuc    static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept
1564684ddb6SLionel Sambuc    {
157*0a6a1f1dSLionel Sambuc        _VSTD::__deallocate (static_cast<void *> (__ptr));
1584684ddb6SLionel Sambuc    }
1594684ddb6SLionel Sambuc
1604684ddb6SLionel Sambucpublic:
1614684ddb6SLionel Sambuc
1624684ddb6SLionel Sambuc    explicit dynarray(size_type __c);
1634684ddb6SLionel Sambuc    dynarray(size_type __c, const value_type& __v);
1644684ddb6SLionel Sambuc    dynarray(const dynarray& __d);
1654684ddb6SLionel Sambuc    dynarray(initializer_list<value_type>);
1664684ddb6SLionel Sambuc
1674684ddb6SLionel Sambuc//  We're not implementing these right now.
168*0a6a1f1dSLionel Sambuc//  Updated with the resolution of LWG issue #2255
1694684ddb6SLionel Sambuc//     template <typename _Alloc>
170*0a6a1f1dSLionel Sambuc//       dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c);
1714684ddb6SLionel Sambuc//     template <typename _Alloc>
172*0a6a1f1dSLionel Sambuc//       dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v);
1734684ddb6SLionel Sambuc//     template <typename _Alloc>
174*0a6a1f1dSLionel Sambuc//       dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d);
1754684ddb6SLionel Sambuc//     template <typename _Alloc>
176*0a6a1f1dSLionel Sambuc//       dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>);
1774684ddb6SLionel Sambuc
1784684ddb6SLionel Sambuc    dynarray& operator=(const dynarray&) = delete;
1794684ddb6SLionel Sambuc    ~dynarray();
1804684ddb6SLionel Sambuc
1814684ddb6SLionel Sambuc    // iterators:
1824684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY iterator       begin()        noexcept { return iterator(data()); }
1834684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_iterator begin()  const noexcept { return const_iterator(data()); }
1844684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
1854684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY iterator       end()          noexcept { return iterator(data() + __size_); }
1864684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_iterator end()    const noexcept { return const_iterator(data() + __size_); }
1874684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_iterator cend()   const noexcept { return const_iterator(data() + __size_); }
1884684ddb6SLionel Sambuc
1894684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rbegin()        noexcept { return reverse_iterator(end()); }
1904684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin()  const noexcept { return const_reverse_iterator(end()); }
1914684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
1924684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rend()          noexcept { return reverse_iterator(begin()); }
1934684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend()    const noexcept { return const_reverse_iterator(begin()); }
1944684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend()   const noexcept { return const_reverse_iterator(begin()); }
1954684ddb6SLionel Sambuc
1964684ddb6SLionel Sambuc    // capacity:
1974684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY size_type size()     const noexcept { return __size_; }
1984684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
1994684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY bool      empty()    const noexcept { return __size_ == 0; }
2004684ddb6SLionel Sambuc
2014684ddb6SLionel Sambuc    // element access:
2024684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       { return data()[__n]; }
2034684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
2044684ddb6SLionel Sambuc
2054684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reference       front()       { return data()[0]; }
2064684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
2074684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reference       back()        { return data()[__size_-1]; }
2084684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reference back()  const { return data()[__size_-1]; }
2094684ddb6SLionel Sambuc
2104684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
2114684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY reference       at(size_type __n);
2124684ddb6SLionel Sambuc
2134684ddb6SLionel Sambuc    // data access:
2144684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY _Tp*       data()       noexcept { return __base_; }
2154684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
2164684ddb6SLionel Sambuc
2174684ddb6SLionel Sambuc    // mutating member functions:
2184684ddb6SLionel Sambuc    inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
2194684ddb6SLionel Sambuc};
2204684ddb6SLionel Sambuc
2214684ddb6SLionel Sambuctemplate <class _Tp>
2224684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2234684ddb6SLionel Sambucdynarray<_Tp>::dynarray(size_type __c) : dynarray ()
2244684ddb6SLionel Sambuc{
2254684ddb6SLionel Sambuc    __base_ = __allocate (__c);
2264684ddb6SLionel Sambuc    value_type *__data = data ();
2274684ddb6SLionel Sambuc    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
2284684ddb6SLionel Sambuc        ::new (__data) value_type;
2294684ddb6SLionel Sambuc}
2304684ddb6SLionel Sambuc
2314684ddb6SLionel Sambuctemplate <class _Tp>
2324684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2334684ddb6SLionel Sambucdynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
2344684ddb6SLionel Sambuc{
2354684ddb6SLionel Sambuc    __base_ = __allocate (__c);
2364684ddb6SLionel Sambuc    value_type *__data = data ();
2374684ddb6SLionel Sambuc    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
2384684ddb6SLionel Sambuc        ::new (__data) value_type (__v);
2394684ddb6SLionel Sambuc}
2404684ddb6SLionel Sambuc
2414684ddb6SLionel Sambuctemplate <class _Tp>
2424684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2434684ddb6SLionel Sambucdynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
2444684ddb6SLionel Sambuc{
2454684ddb6SLionel Sambuc    size_t sz = __il.size();
2464684ddb6SLionel Sambuc    __base_ = __allocate (sz);
2474684ddb6SLionel Sambuc    value_type *__data = data ();
2484684ddb6SLionel Sambuc    auto src = __il.begin();
2494684ddb6SLionel Sambuc    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
2504684ddb6SLionel Sambuc        ::new (__data) value_type (*src);
2514684ddb6SLionel Sambuc}
2524684ddb6SLionel Sambuc
2534684ddb6SLionel Sambuctemplate <class _Tp>
2544684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2554684ddb6SLionel Sambucdynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
2564684ddb6SLionel Sambuc{
2574684ddb6SLionel Sambuc    size_t sz = __d.size();
2584684ddb6SLionel Sambuc    __base_ = __allocate (sz);
2594684ddb6SLionel Sambuc    value_type *__data = data ();
2604684ddb6SLionel Sambuc    auto src = __d.begin();
2614684ddb6SLionel Sambuc    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
2624684ddb6SLionel Sambuc        ::new (__data) value_type (*src);
2634684ddb6SLionel Sambuc}
2644684ddb6SLionel Sambuc
2654684ddb6SLionel Sambuctemplate <class _Tp>
2664684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2674684ddb6SLionel Sambucdynarray<_Tp>::~dynarray()
2684684ddb6SLionel Sambuc{
2694684ddb6SLionel Sambuc    value_type *__data = data () + __size_;
2704684ddb6SLionel Sambuc    for ( size_t i = 0; i < __size_; ++i )
2714684ddb6SLionel Sambuc        (--__data)->value_type::~value_type();
2724684ddb6SLionel Sambuc    __deallocate ( __base_ );
2734684ddb6SLionel Sambuc}
2744684ddb6SLionel Sambuc
2754684ddb6SLionel Sambuctemplate <class _Tp>
2764684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2774684ddb6SLionel Sambuctypename dynarray<_Tp>::reference
2784684ddb6SLionel Sambucdynarray<_Tp>::at(size_type __n)
2794684ddb6SLionel Sambuc{
2804684ddb6SLionel Sambuc    if (__n >= __size_)
2814684ddb6SLionel Sambuc    {
2824684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
2834684ddb6SLionel Sambuc        throw out_of_range("dynarray::at");
2844684ddb6SLionel Sambuc#else
2854684ddb6SLionel Sambuc        assert(!"dynarray::at out_of_range");
2864684ddb6SLionel Sambuc#endif
2874684ddb6SLionel Sambuc    }
2884684ddb6SLionel Sambuc    return data()[__n];
2894684ddb6SLionel Sambuc}
2904684ddb6SLionel Sambuc
2914684ddb6SLionel Sambuctemplate <class _Tp>
2924684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
2934684ddb6SLionel Sambuctypename dynarray<_Tp>::const_reference
2944684ddb6SLionel Sambucdynarray<_Tp>::at(size_type __n) const
2954684ddb6SLionel Sambuc{
2964684ddb6SLionel Sambuc    if (__n >= __size_)
2974684ddb6SLionel Sambuc    {
2984684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS
2994684ddb6SLionel Sambuc        throw out_of_range("dynarray::at");
3004684ddb6SLionel Sambuc#else
3014684ddb6SLionel Sambuc        assert(!"dynarray::at out_of_range");
3024684ddb6SLionel Sambuc#endif
3034684ddb6SLionel Sambuc    }
3044684ddb6SLionel Sambuc    return data()[__n];
3054684ddb6SLionel Sambuc}
3064684ddb6SLionel Sambuc
3074684ddb6SLionel Sambuc}}}
3084684ddb6SLionel Sambuc
3094684ddb6SLionel Sambuc
3104684ddb6SLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_STD
3114684ddb6SLionel Sambuctemplate <class _Tp, class _Alloc>
3124684ddb6SLionel Sambucstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
3134684ddb6SLionel Sambuc_LIBCPP_END_NAMESPACE_STD
3144684ddb6SLionel Sambuc
3154684ddb6SLionel Sambuc#endif  // if _LIBCPP_STD_VER > 11
3164684ddb6SLionel Sambuc#endif  // _LIBCPP_DYNARRAY
317