aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-03-28 09:07:03 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-03-28 09:07:03 +0200
commitb490a93a7a42aa14f0a3e53cfb668666bef82844 (patch)
tree23d3d28fe75fabbc6cde2a5294bc9cc4c6ca6606
parentf0935c0a7055300a42a3e0418e9910fecff2ccb8 (diff)
Add vector_view class template
-rw-r--r--butl/vector-view109
1 files changed, 109 insertions, 0 deletions
diff --git a/butl/vector-view b/butl/vector-view
new file mode 100644
index 0000000..30a786c
--- /dev/null
+++ b/butl/vector-view
@@ -0,0 +1,109 @@
+// file : butl/vector-view -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUTL_VECTOR_VIEW
+#define BUTL_VECTOR_VIEW
+
+#include <vector>
+#include <cstddef> // size_t, ptrdiff_t
+#include <utility> // swap()
+#include <iterator> // reverse_iterator
+#include <stdexcept> // out_of_range
+
+namespace butl
+{
+ // In our version a const view allows the modification of the elements
+ // unless T is made const (the same semantics as in smart pointers).
+ //
+ // @@ If T is const T1, could be useful to have a c-tor from vector<T1>.
+ //
+ template <typename T>
+ class vector_view
+ {
+ public:
+ using value_type = T;
+ using pointer = T*;
+ using reference = T&;
+ using const_pointer = const T*;
+ using const_reference = const T&;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+
+ using iterator = T*;
+ using const_iterator = const T*;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ // construct/copy/destroy:
+ //
+ vector_view (): data_ (nullptr), size_ (0) {}
+ vector_view (T* d, size_type s): data_ (d), size_ (s) {}
+
+ template <typename T1, typename A>
+ vector_view (std::vector<T1, A>& v)
+ : data_ (v.data ()), size_ (v.size ()) {}
+
+ template <typename T1, typename A>
+ vector_view (const std::vector<T1, A>& v)
+ : data_ (v.data ()), size_ (v.size ()) {}
+
+ vector_view (vector_view&&) = default;
+ vector_view (const vector_view&) = default;
+ vector_view& operator= (vector_view&&) = default;
+ vector_view& operator= (const vector_view&) = default;
+
+ // iterators:
+ //
+ iterator begin() const {return data_;}
+ iterator end() const {return data_ + size_;}
+
+ const_iterator cbegin() const {return data_;}
+ const_iterator cend() const {return data_ + size_;}
+
+ reverse_iterator rbegin() const {return reverse_iterator (end ());}
+ reverse_iterator rend() const {return reverse_iterator (begin ());}
+
+ const_reverse_iterator crbegin() const {
+ return const_reverse_iterator (cend ());}
+ const_reverse_iterator crend() const {
+ return const_reverse_iterator (cbegin ());}
+
+ // capacity:
+ //
+ size_type size() const {return size_;}
+ bool empty() const {return size_ == 0;}
+
+ // element access:
+ //
+ reference operator[](size_type n) const {return data_[n];}
+ reference at(size_type n) const {
+ if (n >= size_) throw std::out_of_range (); return data_[n];}
+ reference front() const {return data_[0];}
+ reference back() const {return data_[size_ - 1];}
+
+ // data access:
+ //
+ T* data() const {return data_;}
+
+ // modifiers:
+ //
+ void swap (vector_view& v) {
+ std::swap (data_, v.data_); std::swap (size_, v.size_);}
+
+ private:
+ T* data_;
+ size_type size_;
+ };
+
+ //@@ TODO.
+ //
+ template<typename T> bool operator== (vector_view<T> l, vector_view<T> r);
+ template<typename T> bool operator!= (vector_view<T> l, vector_view<T> r);
+ template<typename T> bool operator< (vector_view<T> l, vector_view<T> r);
+ template<typename T> bool operator> (vector_view<T> l, vector_view<T> r);
+ template<typename T> bool operator<= (vector_view<T> l, vector_view<T> r);
+ template<typename T> bool operator>= (vector_view<T> l, vector_view<T> r);
+}
+
+#endif // BUTL_VECTOR_VIEW