aboutsummaryrefslogtreecommitdiff
path: root/libbutl/vector-view.mxx
blob: 792437187381fece40f8e0b5033c5b1a3dc75445 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// file      : libbutl/vector-view.mxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef __cpp_modules_ts
#pragma once
#endif

// C includes.

#ifndef __cpp_lib_modules_ts
#include <vector>
#include <cstddef>   // size_t, ptrdiff_t
#include <utility>   // swap()
#include <iterator>  // reverse_iterator
#include <stdexcept> // out_of_range
#endif

// Other includes.

#ifdef __cpp_modules_ts
export module butl.vector_view;
#ifdef __cpp_lib_modules_ts
import std.core;
#endif
#endif

#include <libbutl/export.hxx>

LIBBUTL_MODEXPORT 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 ()) {}

    template <typename T1>
    vector_view (const vector_view<T1>& 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  front() const {return data_[0];}
    reference  back() const {return data_[size_ - 1];}

    reference  at(size_type n) const
    {
      if (n >= size_)
        throw std::out_of_range ("index out of range");
      return data_[n];
    }

    // data access:
    //
    T* data() const {return data_;}

    // modifiers:
    //
    void assign (T* d, size_type s) {data_ = d; size_ = s;}
    void clear () {data_ = nullptr; size_ = 0;}
    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);
}