diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-09-06 10:25:54 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-09-06 15:18:33 +0200 |
commit | 4d830ab33c75dc07d77796d422d909c235c2c127 (patch) | |
tree | 40c3fcb363617246dbb5d92c0b94bc5e3e40acdf /include/o3tl | |
parent | bc3e0121b47cc601575b0a49f6ba4959130cf96e (diff) |
const correctness in o3tl::array_view
Change-Id: I44c1ace97ae44069c5a0c6a247aa8a0b49896ad3
Reviewed-on: https://gerrit.libreoffice.org/41985
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'include/o3tl')
-rw-r--r-- | include/o3tl/array_view.hxx | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/include/o3tl/array_view.hxx b/include/o3tl/array_view.hxx index 9da86866680e..bb4818a4c8a0 100644 --- a/include/o3tl/array_view.hxx +++ b/include/o3tl/array_view.hxx @@ -27,8 +27,6 @@ #include <rtl/ustring.hxx> #include <sal/types.h> -// A barebones approximation of C++17(?) <array_view>, haven't bothered with more than single-dimensional arrays - #if HAVE_CXX14_CONSTEXPR #define CONSTEXPR constexpr #else @@ -42,8 +40,12 @@ namespace o3tl { #pragma warning(disable: 4814) // in C++14 'constexpr' will not imply 'const' #endif +/** A barebones approximation of C++17(?) <array_view>. + Haven't bothered with more than single-dimensional arrays. +*/ template<typename T> class array_view { + friend class array_view<T const>; public: using value_type = T; using pointer = value_type *; @@ -51,9 +53,9 @@ public: using reference = value_type &; using const_reference = value_type const &; using const_iterator = const_pointer; - using iterator = const_iterator; + using iterator = pointer; using const_reverse_iterator = std::reverse_iterator<const_iterator>; - using reverse_iterator = const_reverse_iterator; + using reverse_iterator = std::reverse_iterator<iterator>; using size_type = std::size_t; using difference_type = std::ptrdiff_t; @@ -62,9 +64,9 @@ public: constexpr array_view() noexcept : data_(nullptr), size_(0) {} template<size_type N> - CONSTEXPR array_view (T const (&a)[N]) noexcept : data_(a), size_(N) {} + CONSTEXPR array_view (T (&a)[N]) noexcept : data_(a), size_(N) {} - CONSTEXPR array_view (T const *a, size_type len) noexcept + CONSTEXPR array_view (T *a, size_type len) noexcept : data_(a), size_(len) { #if HAVE_CXX14_CONSTEXPR @@ -73,18 +75,36 @@ public: #endif } - constexpr bool empty() const noexcept { return size_ == 0; } + /// Allow for assigning array_view<T> to array_view<T const> i.e. + /// array_view<T> a; + /// array_view<T const> b = a; + template<typename = std::enable_if< std::is_const<value_type>::value > > + array_view& operator=(array_view<typename std::remove_const<value_type>::type> const & other) + { + data_ = other.data_; + size_ = other.size_; + return *this; + } - constexpr const_iterator begin() const noexcept { return data_; } - constexpr const_iterator end() const noexcept { return begin() + size(); } + array_view& operator=(array_view const & other) + { + data_ = other.data_; + size_ = other.size_; + return *this; + } + + constexpr bool empty() const noexcept { return size_ == 0; } + + constexpr iterator begin() const noexcept { return data_; } + constexpr iterator end() const noexcept { return begin() + size(); } constexpr const_iterator cbegin() const noexcept { return begin(); } constexpr const_iterator cend() const noexcept { return end(); } - constexpr const_reverse_iterator rbegin() const noexcept - { return const_reverse_iterator(end()); } - constexpr const_reverse_iterator rend() const noexcept - { return const_reverse_iterator(begin()); } + reverse_iterator rbegin() const noexcept + { return reverse_iterator(end()); } + reverse_iterator rend() const noexcept + { return reverse_iterator(begin()); } constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } @@ -103,7 +123,7 @@ public: return npos - 1; } - constexpr const_reference operator [](size_type pos) const { + constexpr reference operator [](size_type pos) const { #if HAVE_CXX14_CONSTEXPR assert(pos < size()); #endif @@ -111,37 +131,42 @@ public: } CONSTEXPR - const_reference at(size_type pos) const { + reference at(size_type pos) const { if (pos >= size()) { throw std::out_of_range("o3tl::array_view::at"); } return operator [](pos); } - constexpr const_reference front() const { + constexpr reference front() const { #if HAVE_CXX14_CONSTEXPR assert(!empty()); #endif return operator [](0); } - constexpr const_reference back() const { + constexpr reference back() const { #if HAVE_CXX14_CONSTEXPR assert(!empty()); #endif return operator [](size() - 1); } - constexpr const_pointer data() const noexcept { return data_; } + constexpr pointer data() const noexcept { return data_; } CONSTEXPR void swap(array_view & s) noexcept { std::swap(data_, s.data_); std::swap(size_, s.size_); } + /// so we can use it in associative containers + constexpr bool operator<(array_view const & other) const noexcept { + return data_ < other.data_ && size_ < other.size_; + } + private: - const_pointer data_; - size_type size_; + pointer data_; + size_type size_; }; |