// Copyright 2010-2018 Google LLC // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef OR_TOOLS_UTIL_ZVECTOR_H_ #define OR_TOOLS_UTIL_ZVECTOR_H_ #if ( defined(__APPLE__) || defined(__FreeBSD__) ) && defined(__GNUC__) #include #elif !defined(_MSC_VER) #include #endif #include #include #include #include #include #include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" // An array class for storing arrays of integers. // // The range of indices is specified at the construction of the object. // The minimum and maximum indices are inclusive. // Think of the Pascal syntax array[min_index..max_index] of ... // // For example, ZVector(-100000,100000) will store 200001 // signed integers of 32 bits each, and the possible range of indices // will be -100000..100000. namespace operations_research { template class ZVector { public: ZVector() : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() {} ZVector(int64 min_index, int64 max_index) : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() { if (!Reserve(min_index, max_index)) { LOG(DFATAL) << "Could not reserve memory for indices ranging from " << min_index << " to " << max_index; } } int64 min_index() const { return min_index_; } int64 max_index() const { return max_index_; } // Returns the value stored at index. T Value(int64 index) const { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); return base_[index]; } #if !defined(SWIG) // Shortcut for returning the value stored at index. T& operator[](int64 index) { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); return base_[index]; } const T operator[](int64 index) const { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); return base_[index]; } #endif // Sets to value the content of the array at index. void Set(int64 index, T value) { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); base_[index] = value; } // Reserves memory for new minimum and new maximum indices. // Returns true if the memory could be reserved. // Never shrinks the memory allocated. bool Reserve(int64 new_min_index, int64 new_max_index) { if (new_min_index > new_max_index) { return false; } const uint64 new_size = new_max_index - new_min_index + 1; if (base_ != nullptr) { if (new_min_index >= min_index_ && new_max_index <= max_index_) { min_index_ = new_min_index; max_index_ = new_max_index; size_ = new_size; return true; } else if (new_min_index > min_index_ || new_max_index < max_index_) { return false; } } T* new_storage = new T[new_size]; if (new_storage == nullptr) { return false; } T* const new_base = new_storage - new_min_index; if (base_ != nullptr) { T* const destination = new_base + min_index_; memcpy(destination, storage_.get(), size_ * sizeof(*base_)); } base_ = new_base; size_ = new_size; min_index_ = new_min_index; max_index_ = new_max_index; storage_.reset(new_storage); return true; } // Sets all the elements in the array to value. void SetAll(T value) { DLOG_IF(WARNING, base_ == nullptr || size_ <= 0) << "Trying to set values to uninitialized vector."; for (int64 i = 0; i < size_; ++i) { base_[min_index_ + i] = value; } } private: // Pointer to the element indexed by zero in the array. T* base_; // Minimum index for the array. int64 min_index_; // Maximum index for the array. int64 max_index_; // The number of elements in the array. int64 size_; // Storage memory for the array. std::unique_ptr storage_; }; // Shorthands for all the types of ZVector's. typedef ZVector Int8ZVector; typedef ZVector Int16ZVector; typedef ZVector Int32ZVector; typedef ZVector Int64ZVector; typedef ZVector UInt8ZVector; typedef ZVector UInt16ZVector; typedef ZVector UInt32ZVector; typedef ZVector UInt64ZVector; } // namespace operations_research #endif // OR_TOOLS_UTIL_ZVECTOR_H_