gslcpp
Modern-C++ Wrapper for GSL
vector.hpp
Go to the documentation of this file.
1 /// \dir include/gslcpp
2 /// \brief Top-level directory for gslcpp's header-only library.
3 
4 /// \file include/gslcpp/vector.hpp
5 /// \copyright 2022 Thomas E. Vaughan, all rights reserved.
6 /// \brief Definition for gsl::vector.
7 
8 #pragma once
9 
10 #include "vec/v-iface.hpp" // v_iface
11 #include "vec/v-stor.hpp" // v_stor
12 
13 namespace gsl {
14 
15 
16 using std::enable_if_t;
17 using std::is_const_v;
18 
19 
20 /// Constructor-type for vector whose storage is owned by instance of vector.
21 ///
22 /// %vector has its interface to storage given by gsl::v_stor, and most of the
23 /// ordinary vector-interface is given by gsl::v_iface.
24 ///
25 /// %vector inherits these and provides template-constructors for an instance
26 /// of type gsl::v_iface<T, S, v_stor>.
27 ///
28 /// Each constructor copies data from the source or (in the case of the
29 /// move-constructor, when both the source is an r-value with `S = 0`, and the
30 /// destination has `S = 0`) *moves* the data into the instance.
31 ///
32 /// Template-value-parameter `S` indicates the number of elements in the vector
33 /// at compile-time. If `S` be zero, then the number of elements in the vector
34 /// is determined at run-time.
35 ///
36 /// Although move-construction is provided, move-assignment is *not* provided.
37 /// Once a chunk of memory is allocated to a vector, that same chunk, and only
38 /// ever that chunk, is associated with the vector until it is destroyed.
39 ///
40 /// When using %vector, one typically does not need to specify
41 /// template-parameters:
42 ///
43 /// ~~~{.cpp}
44 /// #include <gslcpp/vector.hpp>
45 ///
46 /// int main() {
47 /// double g[]= {1, 2, 3, 4, 5, 6};
48 ///
49 /// // Deduce vector<double, 6> with stride=1, and copy the data:
50 /// gsl::vector v1= g;
51 ///
52 /// // Deduce vector<double, 0> with three elements and stride=2, and copy
53 /// // the data:
54 /// gsl::vector v2(g, 3, 2);
55 ///
56 /// // Deduce vector<double const, 0> with three elements and stride=2, and
57 /// // copy the data:
58 /// double const *h= g;
59 /// gsl::vector v3(h, 3, 2);
60 ///
61 /// return 0;
62 /// }
63 /// ~~~
64 ///
65 /// \tparam T Type of each element in vector.
66 /// \tparam S Compile-time number of elements (0 for number set at run-time).
67 template<typename T, size_t S= 0> struct vector: public v_iface<T, S, v_stor> {
68  using P= v_iface<T, S, v_stor>; ///< Type of ancestor.
69  using P::P;
70 
71  /// Copy data from other vector of same type.
72  /// \param src Reference to other vector.
73  vector(vector const &src): P(src.v()->size) { memcpy(*this, src); }
74 
75  /// Enable move-constructor in gsl::v_stor to work.
76  vector(vector &&)= default;
77 
78  /// Enable explicitly defined copy-constructor in gsl::v_iface.
79  /// \return Reference to this instance after assignment.
80  vector &operator=(vector const &)= default;
81 
82  /// Struct defining whether size of other vector allow copying its data.
83  /// \tparam N Number of elements in other vector.
84  template<size_t N> struct sz_ok {
85  enum { V= (N == S || N == 0 || S == 0) /**< True if N be OK. */ };
86  };
87 
88  /// Copy data from vector of different type (different element-constness,
89  /// different compile-time number of elements, or different
90  /// storage-interface).
91  /// \tparam N Number of elements in other vector.
92  /// \tparam V Type of other vector's interface to storage.
93  /// \param src Reference to other vector.
94  template<
95  size_t N,
96  template<typename, size_t>
97  class V,
98  typename= enable_if_t<sz_ok<N>::V && !is_const_v<T>>>
99  vector(v_iface<T const, N, V> const &src): P(src.v()->size) {
100  memcpy(*this, src);
101  }
102 
103  /// Copy data from vector of different type (different compile-time number of
104  /// elements or different storage-interface).
105  /// \tparam N Number of elements in other vector.
106  /// \tparam V Type of other vector's interface to storage.
107  /// \param src Reference to other vector.
108  template<
109  size_t N,
110  template<typename, size_t>
111  class V,
112  typename= enable_if_t<sz_ok<N>::V>>
113  vector(v_iface<T, N, V> const &src): P(src.v()->size) {
114  memcpy(*this, src);
115  }
116 
117  /// Copy from standard (decayed) C-array.
118  ///
119  /// Arguments are ordered differently from those given to
120  /// gsl_vector_viewiew_array_with_stride(). Putting stride at *end* allows
121  /// it to have default value of 1.
122  ///
123  /// \param d Pointer to first element of array and of vector.
124  /// \param n Number of elements in vector.
125  /// \param s Stride of elements relative to array.
126  vector(T const *d, size_t n, size_t s= 1): P(n) {
127  auto const cview= w_vector_view_array(d, s, n);
128  memcpy(*this, v_iface<T const, 0, v_view>(cview));
129  }
130 
131  /// Copy from non-decayed C-array.
132  /// \param d Reference to non-decayed C-array.
133  vector(T const (&d)[S]): P(S) {
134  auto const cview= w_vector_view_array(d, 1, S);
135  memcpy(*this, v_iface<T const, S, v_view>(cview));
136  }
137 
138  /// Copy from initializer-list.
139  /// \param i List of initializers.
140  vector(std::initializer_list<T> i): P(i.size()) {
141  auto const cview= w_vector_view_array(i.begin(), 1, i.size());
142  memcpy(*this, v_iface<T const, 0, v_view>(cview));
143  }
144 };
145 
146 
147 } // namespace gsl
148 
149 // EOF
gsl::vector::vector
vector(v_iface< T const, N, V > const &src)
Copy data from vector of different type (different element-constness, different compile-time number o...
Definition: vector.hpp:99
gsl::vector::vector
vector(T const *d, size_t n, size_t s=1)
Copy from standard (decayed) C-array.
Definition: vector.hpp:126
gsl::vector::vector
vector(vector const &src)
Copy data from other vector of same type.
Definition: vector.hpp:73
gsl::vector::sz_ok::V
@ V
True if N be OK.
Definition: vector.hpp:85
gsl::v_stor
Generic v_stor is interface to storage with two key properties: (1) that size of storage is known sta...
Definition: v-stor.hpp:22
gsl::vector::vector
vector(T const (&d)[S])
Copy from non-decayed C-array.
Definition: vector.hpp:133
gsl::vector::vector
vector(vector &&)=default
Enable move-constructor in gsl::v_stor to work.
gsl::vector::vector
vector(v_iface< T, N, V > const &src)
Copy data from vector of different type (different compile-time number of elements or different stora...
Definition: vector.hpp:113
gsl::vector::vector
vector(std::initializer_list< T > i)
Copy from initializer-list.
Definition: vector.hpp:140
gsl::v_iface
Interface for every kind of vector.
Definition: v-iface.hpp:62
gsl::v_view
Interface to vector-storage not owned by interface.
Definition: v-view.hpp:17
gsl::vector::operator=
vector & operator=(vector const &)=default
Enable explicitly defined copy-constructor in gsl::v_iface.
gsl::vector
Constructor-type for vector whose storage is owned by instance of vector.
Definition: vector.hpp:67
gsl::vector::sz_ok
Struct defining whether size of other vector allow copying its data.
Definition: vector.hpp:84
gsl
Namespace for C++-interface to GSL.
Definition: v-iface.hpp:51