//# Vector.cc: A 1-D Specialization of the Array Class //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_VECTOR_2_TCC #define CASA_VECTOR_2_TCC #include "Vector.h" #include "ArrayError.h" #include "Slice.h" #include "MaskedArray.h" #include #include namespace casacore { //#Begin casa namespace template Vector::Vector() : Array(IPosition(1,0)) { assert(ok()); } template Vector::Vector(size_t Length) : Array(IPosition(1, Length)) { assert(ok()); } template Vector::Vector(const IPosition& len) : Array(len) { Array::checkBeforeResize(len); } template Vector::Vector(size_t length, const T &initialValue) : Array(IPosition(1, length), initialValue) { assert(ok()); } template Vector::Vector(const IPosition& length, const T &initialValue) : Array(length, initialValue) { Array::checkBeforeResize(length); } template Vector::Vector(size_t length, typename Array::uninitializedType, const Alloc& allocator) : Array(IPosition(1, length), Array::uninitialized, allocator) { } template Vector::Vector(const IPosition& length, typename Array::uninitializedType, const Alloc& allocator) : Array(length, Array::uninitialized, allocator) { Array::checkBeforeResize(length); } template Vector::Vector(const std::vector &other, long long nr) : Array(IPosition(1, other.size())) { initVector (other, nr); assert(ok()); } template Vector::Vector(const std::vector &other, const Alloc& allocator) : Array(IPosition(1, other.size()), const_cast(other.data()), allocator) { assert(ok()); } template<> inline Vector>::Vector(const std::vector& input, const std::allocator& allocator) : Array>(IPosition(1, input.size()), input.begin(), allocator) { assert(ok()); } template template Vector::Vector(InputIterator startIter, InputIterator endIter, const Alloc& allocator) : Vector(startIter, endIter, allocator, std::is_integral()) { } // Constructor for Vector(nonintegral, nonintegral, allocator) template template Vector::Vector(InputIterator startIter, InputIterator endIter, const Alloc& allocator, std::false_type) : Array(IPosition(1, std::distance(startIter, endIter)), startIter, allocator) { assert(ok()); } // Constructor for Vector(integral, integral, allocator) template template Vector::Vector(Integral length, Integral initialValue, const Alloc& allocator, std::true_type) : Array(IPosition(1, length), initialValue, allocator) { assert(ok()); } template Vector::Vector(std::initializer_list list) : Array(list) { assert(ok()); } template Vector::Vector(const Vector &other) : Array(other) { assert(ok()); } template Vector::Vector(Vector&& source) noexcept : Array(std::move(source), IPosition(1, 0)) { assert(ok()); } // // ArrayNDimError // template Vector::Vector(const Array &other) : Array(other) { // If not 1 dimension, adjust shape if possible. if (this->ndim() != 1) { this->checkVectorShape(); } assert(ok()); } template Vector::Vector(const IPosition &shape, T *storage, StorageInitPolicy policy) : Array(shape, storage, policy) { } template Vector::Vector(const IPosition &shape, T *storage, StorageInitPolicy policy, Alloc& allocator) : Array(shape, storage, policy, allocator) { } template Vector::Vector(const IPosition &shape, const T *storage) : Array(shape, storage) { } // Copy from the block. Copy the number of elements specified or // the number of elements in the block if nr <= 0. // // ArrayError // template void Vector::initVector(const std::vector &other, long long nr) { size_t n = nr; if (nr <= 0) { n = other.size(); } if (n > other.size()) throw(ArrayError("Vector::initVector(const Block &other" ", long long nr) - nr > other.nelements()")); if (this->nelements() != n) { this->resize(n); } for (size_t i=0; i < n; i++) { this->begin_p[i] = other[i]; } return; } // // ArrayConformanceError // template void Vector::resize(const IPosition& l, bool copyValues) { assert(ok()); if (copyValues) { Vector oldref(*this); Array::resize(l, false); size_t minNels = std::min(this->nelements(), oldref.nelements()); move_n_with_stride(oldref.begin_p, minNels, this->begin_p, this->inc_p(0), oldref.inc_p(0)); } else { Array::resize(l, false); } assert(ok()); } template Vector& Vector::assign_conforming(const Array& a) { assert(ok()); Vector tmp(a); assign_conforming(tmp); return *this; } template Vector& Vector::assign_conforming(Array&& a) { assert(ok()); Vector tmp(std::move(a)); assign_conforming(tmp); return *this; } template Vector& Vector::assign_conforming_implementation(const Vector &, std::false_type /*movable?*/) { throw std::runtime_error("assign called for which a copy is required, while element type is not copyable"); } template Vector& Vector::assign_conforming_implementation(const Vector &other, std::true_type /*movable?*/) { assert(ok()); if (this != &other) { if (! this->copyVectorHelper (other)) { // Block was empty, so allocate new block. // TODO think about semantics of allocator! this->data_p.reset( new arrays_internal::Storage(this->length_p(0), other.data_p->get_allocator()) ); this->begin_p = this->data_p->data(); } this->setEndIter(); copy_n_with_stride (other.begin_p, this->nels_p, this->begin_p, this->inc_p(0), other.inc_p(0)); } return *this; } template Vector& Vector::assign_conforming(Vector&& source) { assert(ok()); if(this->nrefs() > 1 || source.nrefs() > 1 || this->data_p->is_shared() || source.data_p->is_shared()) assign_conforming(source); else if(source.ndim() == 0) { Vector empty; casacore::swap(empty, *this); } else casacore::swap(source, *this); return *this; } // // ArrayError // template Vector Vector::operator()(const Slice &slice) { assert(ok()); long long b, l, s; // begin length step if (slice.all()) { b = 0; l = this->length_p(0); s = 1; } else { b = slice.start(); l = slice.length(); s = slice.inc(); } // Check that the selected slice is valid if (s < 1) { throw(ArrayError("Vector::operator()(Slice) : step < 1")); } else if (l < 0) { throw(ArrayError("Vector::operator()(Slice) : length < 0")); } else if (b+(l-1)*s >= this->length_p(0)) { throw(ArrayError("Vector::operator()(Slice) : Desired slice extends" " beyond the end of the array")); } else if (b < 0) { throw(ArrayError("Vector::operator()(Slice) : start of slice before " "beginning of vector")); } // Create the slice. This could also be done with the Array::operator() // slice functions, however it's simple for vectors, and this will be // more efficient. // Create the vector that will be the slice into this Vector vp(*this); // Increment vp's begin so that it is at the selected position vp.begin_p += b*this->steps()[0]; vp.inc_p(0) *= s; vp.length_p(0) = l; vp.nels_p = l; vp.contiguous_p = vp.isStorageContiguous(); vp.makeSteps(); return vp; } template const Vector Vector::operator() (const Slice &slice) const { return const_cast*>(this)->operator() (slice); } template void Vector::doNonDegenerate (const Array &other, const IPosition &ignoreAxes) { Array tmp(*this); tmp.nonDegenerate (other, ignoreAxes); Array::reference (tmp); } template bool Vector::ok() const { return this->ndim() == 1 && Array::ok(); } //# Declare extern templates for often used types. extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; extern template class Vector; } //#End casa namespace #endif