Advertisement
zhangsongcui

dynarray

Jun 11th, 2014
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.95 KB | None | 0 0
  1. #include <algorithm>
  2. #include <stdexcept>
  3. #include <new>
  4. #include <cstdint>
  5. #include <cassert>
  6.  
  7. #ifdef _MSC_VER
  8. #   define noexcept throw()
  9. #endif
  10.  
  11. class dynarray_storage {
  12. protected:
  13.     dynarray_storage(std::size_t size) : _size(size) {
  14.         if (size_t(std::end(_buffer) - _ptr) <= size) {
  15.             throw std::bad_alloc();
  16.         }
  17.         _ptr += _size;
  18.     }
  19.  
  20.     ~dynarray_storage() {
  21.         _ptr -= _size;
  22.     }
  23.  
  24.     void* allocated_ptr() const noexcept {
  25.         return _ptr - _size;
  26.     }
  27.  
  28. private:
  29.     size_t _size;
  30.  
  31. private:
  32.     static std::uint8_t _buffer[10240];
  33.     static std::uint8_t* _ptr;
  34. };
  35.  
  36. std::uint8_t dynarray_storage::_buffer[10240];
  37. std::uint8_t* dynarray_storage::_ptr = dynarray_storage::_buffer;
  38.  
  39. // The header <dynarray> defines a class template for storing sequences of objects where the size is fixed at construction. A dynarray supports random access iterators. An instance of dynarray<T> stores elements of type T. The elements of a dynarray are stored contiguously, meaning that if d is an dynarray<T> then it obeys the identity &d[n] == &d[0] + n for all 0 <= n < d.size().
  40. // Unless otherwise specified, all dynarray operations have the same requirements and semantics as specified in 23.2.
  41. // All operations except construction, destruction, and fill shall have constant-time complexity.
  42. template <class T>
  43. class dynarray : private dynarray_storage {
  44.     // types:
  45.     typedef       T                               value_type;
  46.     typedef       T&                              reference;
  47.     typedef const T&                              const_reference;
  48.     typedef       T*                              pointer;
  49.     typedef const T*                              const_pointer;
  50.     typedef pointer                               iterator;       // See [container.requirements]
  51.     typedef const_pointer                         const_iterator; // See [container.requirements]
  52.     typedef std::reverse_iterator<iterator>       reverse_iterator;
  53.     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  54.     typedef std::size_t                           size_type;
  55.     typedef std::ptrdiff_t                        difference_type;
  56.  
  57. public:
  58.     // [dynarray.cons] construct/copy/destroy:
  59.     explicit dynarray(size_type c)
  60.         : dynarray_storage(elem_size * c)
  61.         , _ptr(static_cast<T *>(allocated_ptr()))
  62.         , _size(c) {
  63.         assert(_ptr);
  64.         for (auto it = begin(); it != end(); ++it) {
  65.             ::new(&*it) T;
  66.         }
  67.     }
  68.     //template< typename Alloc >
  69.     //    dynarray(size_type c, const Alloc& alloc);
  70.     dynarray(size_type c, const T& v)
  71.         : dynarray_storage(elem_size * c)
  72.         , _ptr(static_cast<T *>(allocated_ptr()))
  73.         , _size(c) {
  74.         assert(_ptr);
  75.         std::uninitialized_fill(_ptr, _ptr + c, v);
  76.     }
  77.     //template< typename Alloc >
  78.     //  dynarray(size_type c, const T& v, const Alloc& alloc);
  79.     //dynarray(const dynarray& d);
  80.     //template< typename Alloc >
  81.     //  dynarray(const dynarray& d, const Alloc& alloc);
  82.     dynarray(std::initializer_list<T> l)
  83.         : dynarray_storage(elem_size * l.size())
  84.         , _ptr(static_cast<T *>(allocated_ptr()))
  85.         , _size(l.size()) {
  86.         assert(_ptr);
  87.         std::uninitialized_copy(l.begin(), l.end(), begin());
  88.     }
  89.     //template< typename Alloc >
  90.     //  dynarray(initializer_list<T>, const Alloc& alloc);
  91.     ~dynarray() {
  92.         for (auto& elem : *this) {
  93.             elem.~T();
  94.         }
  95.     }
  96.  
  97.     dynarray& operator=(const dynarray&) = delete;
  98.  
  99.     // iterators:
  100.     iterator       begin()        noexcept {
  101.         return iterator(data());
  102.     }
  103.     const_iterator begin()  const noexcept {
  104.         return const_iterator(data());
  105.     }
  106.     const_iterator cbegin() const noexcept {
  107.         return const_iterator(data());
  108.     }
  109.     iterator       end()          noexcept {
  110.         return begin() + size();
  111.     }
  112.     const_iterator end()    const noexcept {
  113.         return begin() + size();
  114.     }
  115.     const_iterator cend()   const noexcept {
  116.         return cbegin() + size();
  117.     }
  118.  
  119.     reverse_iterator       rbegin()        noexcept {
  120.         return reverse_iterator(end());
  121.     }
  122.     const_reverse_iterator rbegin()  const noexcept {
  123.         return const_reverse_iterator(end());
  124.     }
  125.     const_reverse_iterator crbegin() const noexcept {
  126.         return const_reverse_iterator(cend());
  127.     }
  128.     reverse_iterator       rend()          noexcept {
  129.         return reverse_iterator(begin());
  130.     }
  131.     const_reverse_iterator rend()    const noexcept {
  132.         return const_reverse_iterator(begin());
  133.     }
  134.     const_reverse_iterator crend()   const noexcept {
  135.         return const_reverse_iterator(cbegin());
  136.     }
  137.  
  138.     // capacity:
  139.     size_type size()     const noexcept {
  140.         return _size;
  141.     }
  142.     size_type max_size() const noexcept {
  143.         return _size;
  144.     }
  145.     bool      empty()    const noexcept {
  146.         return size() != 0;
  147.     }
  148.  
  149.     // element access:
  150.     reference       operator[](size_type n)       noexcept {
  151.         assert(n >= 0 && n < size());
  152.         return data()[n];
  153.     }
  154.     const_reference operator[](size_type n) const noexcept {
  155.         assert(n >= 0 && n < size());
  156.         return data()[n];
  157.     }
  158.  
  159.     reference       front()       noexcept {
  160.         assert(size() > 0);
  161.         return *begin();
  162.     }
  163.     const_reference front() const noexcept {
  164.         assert(size() > 0);
  165.         return *cbegin();
  166.     }
  167.     reference       back()        noexcept {
  168.         assert(size() > 0);
  169.         return *rbegin();
  170.     }
  171.     const_reference back()  const noexcept {
  172.         assert(size() > 0);
  173.         return *crbegin();
  174.     }
  175.  
  176.     reference       at(size_type n) {
  177.         if (n < 0 || n >= size())
  178.             throw std::length_error("at");
  179.         return (*this)[n];
  180.     }
  181.     const_reference at(size_type n) const {
  182.         if (n < 0 || n >= size())
  183.             throw std::length_error("at");
  184.         return (*this)[n];
  185.     }
  186.  
  187.     // [dynarray.data] data access:
  188.     T*       data()       noexcept {
  189.         return _ptr;
  190.     }
  191.     const T* data() const noexcept {
  192.         return _ptr;
  193.     }
  194.  
  195.     // [dynarray.mutate] mutating member functions:
  196.     void fill(const T& v) {
  197.         std::fill(begin(), end(), v);
  198.     }
  199.  
  200. private:
  201.     value_type*     _ptr;
  202.     size_type       _size;
  203.     const static size_t elem_size = sizeof(T);
  204. };
  205.  
  206. #include <string>
  207. #include <vector>
  208.  
  209. int main() {
  210.     for (int i = 0; i<10000; ++i) {
  211.         dynarray<int> test(100, 10000);
  212.     }
  213.     try
  214.     {
  215.         dynarray<std::string> a(3, "aaaaa");
  216.         {
  217.             dynarray<std::string> b(2, "b");
  218.             dynarray<std::string> c(3);
  219.         }
  220.         dynarray<std::string> d(3, "ddddd");
  221.         {
  222.             dynarray<std::string> e(10000000);
  223.         }
  224.     } catch (std::bad_alloc&) {
  225.         for (int i = 0; i<10000; ++i) {
  226.             dynarray<int> test(10);
  227.         }
  228.     }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement