atlas
vector.h
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #pragma once
12 
13 #include <type_traits>
14 #include <utility> // std::swap
15 
16 #include "atlas/library/config.h"
17 #include "atlas/parallel/omp/copy.h"
18 #include "atlas/parallel/omp/fill.h"
19 #include "atlas/runtime/Exception.h"
20 
21 namespace atlas {
22 
23 template <typename T>
24 class vector {
25 public:
26  using value_type = T;
27  using iterator = T*;
28  using const_iterator = T const*;
29 
30 public:
31  vector() = default;
32 
33  template <typename size_t, typename std::enable_if<std::is_integral<size_t>::value, int>::type = 0>
34  vector( size_t size ) {
35  resize( size );
36  }
37 
38  template <typename size_t, typename std::enable_if<std::is_integral<size_t>::value, int>::type = 0>
39  vector( size_t size, const value_type& value ) : vector( size ) {
40  assign( size, value );
41  }
42 
43  vector( const vector& other ) { assign( other.data_, other.data_ + other.size_ ); }
44 
45  vector( vector&& other ) {
46  std::swap( data_, other.data_ );
47  std::swap( size_, other.size_ );
48  std::swap( capacity_, other.capacity_ );
49  }
50 
51  vector& operator=( vector other ) {
52  std::swap( data_, other.data_ );
53  std::swap( size_, other.size_ );
54  std::swap( capacity_, other.capacity_ );
55  return *this;
56  }
57 
58  template <typename T2>
59  vector( const std::initializer_list<T2>& list ) {
60  assign( list.begin(), list.end() );
61  }
62 
63  ~vector() {
64  if ( data_ ) {
65  delete[] data_;
66  }
67  }
68 
69  template <typename idx_t, typename std::enable_if<std::is_integral<idx_t>::value, int>::type = 0>
70  T& at( idx_t i ) noexcept( false ) {
71  if ( i >= size_ ) {
72  throw_OutOfRange( "atlas::vector", i, size_ );
73  }
74  return data_[i];
75  }
76 
77  template <typename idx_t, typename std::enable_if<std::is_integral<idx_t>::value, int>::type = 0>
78  T const& at( idx_t i ) const noexcept( false ) {
79  if ( i >= size_ ) {
80  throw_OutOfRange( "atlas::vector", i, size_ );
81  }
82  return data_[i];
83  }
84 
85  template <typename idx_t, typename std::enable_if<std::is_integral<idx_t>::value, int>::type = 0>
86  T& operator[]( idx_t i ) {
87 #if ATLAS_VECTOR_BOUNDS_CHECKING
88  return at( i );
89 #else
90  return data_[i];
91 #endif
92  }
93 
94  template <typename idx_t, typename std::enable_if<std::is_integral<idx_t>::value, int>::type = 0>
95  T const& operator[]( idx_t i ) const {
96 #if ATLAS_VECTOR_BOUNDS_CHECKING
97  return at( i );
98 #else
99  return data_[i];
100 #endif
101  }
102 
103  const T* data() const { return data_; }
104 
105  T* data() { return data_; }
106 
107  idx_t size() const { return size_; }
108 
109  template <typename Size, typename std::enable_if<std::is_integral<Size>::value, int>::type = 0>
110  void assign( Size n, const value_type& value ) {
111  resize( n );
112  omp::fill( begin(), begin() + n, value );
113  }
114 
115  template <typename Iter, typename std::enable_if<!std::is_integral<Iter>::value, int>::type = 0>
116  void assign( const Iter& first, const Iter& last ) {
117  size_t size = std::distance( first, last );
118  resize( size );
119  omp::copy( first, last, begin() );
120  }
121 
122  template <typename Size, typename std::enable_if<std::is_integral<Size>::value, int>::type = 0>
123  void reserve( Size size ) {
124  if ( capacity_ != 0 )
125  ATLAS_NOTIMPLEMENTED;
126  data_ = new T[size];
127  capacity_ = size;
128  }
129  template <typename size_t, typename std::enable_if<std::is_integral<size_t>::value, int>::type = 0>
130  void resize( size_t size ) {
131  if ( static_cast<idx_t>( size ) > 0 ) {
132  if ( capacity_ == 0 ) {
133  reserve( size );
134  }
135  if ( static_cast<idx_t>( size ) > capacity_ ) {
136  ATLAS_NOTIMPLEMENTED;
137  }
138  size_ = size;
139  }
140  }
141  const_iterator begin() const { return data_; }
142  const_iterator end() const { return data_ + size_; }
143  iterator begin() { return data_; }
144  iterator end() { return data_ + size_; }
145  const_iterator cbegin() const { return data_; }
146  const_iterator cend() const { return data_ + size_; }
147 
148 private:
149  value_type* data_{nullptr};
150  idx_t size_{0};
151  idx_t capacity_{0};
152 };
153 
154 } // namespace atlas
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42