1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: preallocarray.h
4 // Copyright (C) 2014 Toru Shiozaki
5 //
6 // Author: Toru Shiozaki <shiozaki@northwestern.edu>
7 // Maintainer: Shiozaki group
8 //
9 // This file is part of the BAGEL package.
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 //
24 
25 #ifndef __SRC_MATH_PREALLOCARRAY_H
26 #define __SRC_MATH_PREALLOCARRAY_H
27 
28 #include <complex>
29 #include <stdexcept>
30 
31 namespace bagel {
32 
33 template <class DataType>
34 class PreAllocArray {
35   public:
36     using value_type = DataType;
37     using size_type = std::size_t;
38     using difference_type = std::ptrdiff_t;
39     using iterator = DataType*;
40     using reference = DataType&;
41 
42     using const_value_type = const typename std::remove_cv<DataType>::type;
43     using const_iterator = const typename std::remove_cv<DataType>::type*;
44     using const_reference = const typename std::remove_cv<DataType>::type&;
45 
46   protected:
47     DataType* begin_;
48     DataType* end_;
49 
50   public:
PreAllocArray()51     PreAllocArray() : begin_(0), end_(0) { }
PreAllocArray(DataType * b,size_t size)52     PreAllocArray(DataType* b, size_t size) : begin_(b), end_(b+size) { }
PreAllocArray(DataType * b,DataType * e)53     PreAllocArray(DataType* b, DataType* e) : begin_(b), end_(e) { }
PreAllocArray(const PreAllocArray<DataType> & o)54     PreAllocArray(const PreAllocArray<DataType>& o) : begin_(o.begin_), end_(o.end_) { }
55 
56     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
begin()57     iterator begin() { return begin_; }
begin()58     const_iterator begin() const { return begin_; }
cbegin()59     const_iterator cbegin() const { return begin_; }
60 
61     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
end()62     iterator end() { return end_; }
end()63     const_iterator end() const { return end_; }
cend()64     const_iterator cend() const { return end_; }
65 
size()66     size_t size() const { return std::distance(begin_, end_); }
67 
resize(const int)68     void resize(const int) { throw std::logic_error("resize is not allowed in PreAllocArray"); }
empty()69     bool empty() const { return begin_ == end_; }
70 
71     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
at(const size_t i)72     value_type& at(const size_t i) { return *(begin_+i); }
at(const size_t i)73     const_value_type& at(const size_t i) const { return *(begin_+i); }
74 
75     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
front()76     value_type& front() { return at(0); }
front()77     const_value_type& front() const { return at(0); }
78     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
back()79     value_type& back() { return at(size()); }
back()80     const_value_type& back() const { return at(size()); }
81 
82     template <typename T = DataType, class = typename std::enable_if<not std::is_const<T>::value>::type>
data()83     iterator data() { return begin_; }
data()84     const_iterator data() const { return begin_; }
85 
86     PreAllocArray<DataType>& operator=(const PreAllocArray<DataType>& o) { begin_ = o.begin_; end_ = o.end_; return *this; }
87 };
88 
89 }
90 
91 extern template class bagel::PreAllocArray<double>;
92 extern template class bagel::PreAllocArray<std::complex<double>>;
93 extern template class bagel::PreAllocArray<const double>;
94 extern template class bagel::PreAllocArray<const std::complex<double>>;
95 
96 #endif
97