diff --git a/util/const_int_array.cc b/util/const_int_array.cc index 80e8b9aff1..d0baf29c6e 100644 --- a/util/const_int_array.cc +++ b/util/const_int_array.cc @@ -109,7 +109,7 @@ ConstIntArray::SortedCopyWithoutDuplicates(bool increasing) const { } } -bool ConstIntArray::Equals(const ConstIntArray& other) { +bool ConstIntArray::Equals(const ConstIntArray& other) const { if (data_->size() != other.data_->size()) { return false; } diff --git a/util/const_int_array.h b/util/const_int_array.h index e54fc73e26..85cbab3741 100644 --- a/util/const_int_array.h +++ b/util/const_int_array.h @@ -104,7 +104,7 @@ class ConstIntArray { std::vector* SortedCopyWithoutDuplicates(bool increasing) const; // Equality test. - bool Equals(const ConstIntArray& other); + bool Equals(const ConstIntArray& other) const; // Size of the array. This is not valid after Release() has been called. int size() const; diff --git a/util/const_ptr_array.h b/util/const_ptr_array.h new file mode 100644 index 0000000000..fb8f9b8ddb --- /dev/null +++ b/util/const_ptr_array.h @@ -0,0 +1,108 @@ +// Copyright 2010-2011 Google +// 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_CONST_PTR_ARRAY_H_ +#define OR_TOOLS_UTIL_CONST_PTR_ARRAY_H_ + + +using std::string; + +#include +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "util/string_array.h" +#include "base/concise_iterator.h" + +namespace operations_research { +// This class is used to store an const array of T*. +// This is useful inside constraints and expressions. The constructors, +// except the one with the pointer to a vector of cells will copy the +// data internally and will not take ownership of the data passed in +// argument. +// Its goals are: +// - to unify the construction code across the optimization libraries. +// - to provide one code to modify these mappings and apply +// transformations like sorting. +// It requires T to implement a method string T::DebugString() const; +template class ConstPtrArray { + public: + // Build from 1 vector. Copy the data internally. + explicit ConstPtrArray(const std::vector& ptrs) + : data_(new std::vector(ptrs)) {} + + // Build from one data vector. Takes ownership of the vector. + explicit ConstPtrArray(std::vector* const data) : data_(data) {} + + // This code releases the ownership of the data into the returned vector. + // After this method is called, data_ points to a null vector. + std::vector* Release() { + return data_.release(); + } + + // Size of the array. This is not valid after Release() has been called. + int size() const { + if (data_.get() == NULL) { + return 0; + } + return data_->size(); + } + + // Checks for deep equality with other array. + bool Equals(const ConstPtrArray& other) const { + const int current_size = size(); + if (current_size != other.size()) { + return false; + } + for (int i = 0; i < current_size; ++i) { + if (get(i) != other.get(i)) { + return false; + } + } + return true; + } + + // Returns the instance of T* at position index. This is not valid + // after Release() has been called. + T* operator[](int64 index) const { + CHECK_NOTNULL(data_.get()); + return (*data_)[index]; + } + + // Returns the instance of T* at position index. This is not valid + // after Release() has been called. + T* get(int64 index) const { + CHECK_NOTNULL(data_.get()); + return (*data_)[index]; + } + + // Returns a copy of the data. Usually used to create a new ConstPtrArray. + std::vector* Copy() const { + CHECK_NOTNULL(data_.get()); + return new std::vector(*data_); + } + + // Pretty print. + string DebugString() const { + if (data_.get() == NULL) { + return "Released ConstPtrArray"; + } + return StringPrintf("[%s]", DebugStringArray(data_->data(), + data_->size(), ", ").c_str()); + } + + private: + scoped_ptr > data_; +}; + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_CONST_PTR_ARRAY_H_ diff --git a/util/string_array.h b/util/string_array.h new file mode 100644 index 0000000000..467c8fb99f --- /dev/null +++ b/util/string_array.h @@ -0,0 +1,69 @@ +// Copyright 2010-2011 Google +// 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_STRING_ARRAY_H_ +#define OR_TOOLS_UTIL_STRING_ARRAY_H_ + +#include +#include "base/stringprintf.h" + +using std::string; + +namespace operations_research { +// ---------- Pretty Print Helpers ---------- + +// Creates a string from an array of objects supporting the +// DebugString() method, and a separator. +template string DebugStringArray(T* const* array, + int size, + const string& separator) { + string out; + for (int i = 0; i < size; ++i) { + if (i > 0) { + out.append(separator); + } + out.append(array[i]->DebugString()); + } + return out; +} + +// Creates a string from an array of objects supporting the +// name() method, and a separator. +template string NameArray(T* const* array, + int size, + const string& separator) { + string out; + for (int i = 0; i < size; ++i) { + if (i > 0) { + out.append(separator); + } + out.append(array[i]->name()); + } + return out; +} + +// Creates a string from an array of int64, and a separator. +inline string Int64ArrayToString(const int64* const array, + int size, + const string& separator) { + string out; + for (int i = 0; i < size; ++i) { + if (i > 0) { + out.append(separator); + } + StringAppendF(&out, "%" GG_LL_FORMAT "d", array[i]); + } + return out; +} +} // namespace +#endif // OR_TOOLS_UTIL_STRING_ARRAY_H_ diff --git a/util/vector_map.h b/util/vector_map.h new file mode 100644 index 0000000000..e710845ac5 --- /dev/null +++ b/util/vector_map.h @@ -0,0 +1,108 @@ +// Copyright 2010-2011 Google +// 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. + +// Vector with map from element to index in the vector. + +#ifndef OR_TOOLS_UTIL_VECTOR_MAP_H_ +#define OR_TOOLS_UTIL_VECTOR_MAP_H_ + +#include "base/hash.h" +#include +#include "base/map-util.h" + +namespace operations_research { + +// This class stores a vector of distinct elements, as well as a map +// from elements to index to find the index in the vector. +// This is useful to store mapping between objects and indices. +template class VectorMap { + public: + // Adds an element if not already present, and returns its index in + // the vector-map. + int Add(const T& element) { + int current_index = Index(element); + if (current_index != -1) { + return current_index; + } + const int index = list_.size(); + CHECK_EQ(index, map_.size()); + list_.push_back(element); + map_[element] = index; + return index; + } + // TODO(user): Use ArraySlice. + + // Adds all elements of the vector. + void Add(const std::vector& elements) { + for (int i = 0; i < elements.size(); ++i) { + Add(elements[i]); + } + } + + // Returns -1 if the element is not in the vector, or its unique + // index if it is. + int Index(const T& element) const { + return FindWithDefault(map_, element, -1); + } + // TODO(user): explore a int-type version. + + // Returns wether the element has already been added to the vector-map. + bool Contains(const T& element) const { + return ContainsKey(map_, element); + } + + // Returns the element at position index. + const T& Element(int index) const { + CHECK_GE(index, 0); + CHECK_LT(index, list_.size()); + return list_[index]; + } + + // Returns the number of distinct elements added to the vector-map. + int size() const { return list_.size(); } + + // Clears all the elements added to the vector-map. + void clear() { + list_.clear(); + map_.clear(); + } + + // Returns a read-only access to the vector of elements. + const std::vector& list() const { return list_; } + + // Standard STL container boilerplate. + typedef T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef const T& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static const size_type npos; + typedef const T* const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + const_iterator begin() const { return list_.data(); } + const_iterator end() const { return list_.data() + list_.size(); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(list_.data() + list_.size()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(list_.data()); + } + + private: + std::vector list_; + hash_map map_; +}; + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_VECTOR_MAP_H_