From 76729f9670ba63a9146079b081bdb5b5ae0bbd3d Mon Sep 17 00:00:00 2001 From: Kenny Ballou Date: Fri, 28 Feb 2020 15:36:09 -0700 Subject: CASA fork: initial commit Snapshot from http://cse.unl.edu/~citportal/. --- common/utility/SubstitutionArray.H | 191 +++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 common/utility/SubstitutionArray.H (limited to 'common/utility/SubstitutionArray.H') diff --git a/common/utility/SubstitutionArray.H b/common/utility/SubstitutionArray.H new file mode 100644 index 0000000..48bfbca --- /dev/null +++ b/common/utility/SubstitutionArray.H @@ -0,0 +1,191 @@ +// Copyright 2008, 2009 Brady J. Garvin + +// This file is part of Covering Arrays by Simulated Annealing (CASA). + +// CASA is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// CASA 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with CASA. If not, see . + + +#ifndef SUBSTITUTION_ARRAY_H +#define SUBSTITUTION_ARRAY_H + +#include +#include + +#include "Array.H" +#include "Lazy.H" + +#ifndef MAXIMUM_SUBSTITUTION_PROPORTION +#define MAXIMUM_SUBSTITUTION_PROPORTION 0.1F +#endif + +templateclass SubstitutionArray : protected Array { +protected: + Lazy > substitutions; + unsigned maximumSubstitutions; + +public: + SubstitutionArray() : Array() {} + SubstitutionArray(unsigned size) : + Array(size), + maximumSubstitutions(MAXIMUM_SUBSTITUTION_PROPORTION * size) {} + SubstitutionArray(const T*raw, unsigned size) : + Array(raw, size), + maximumSubstitutions(MAXIMUM_SUBSTITUTION_PROPORTION * size) {} + SubstitutionArray(const Array©) : + Array(copy), + maximumSubstitutions(MAXIMUM_SUBSTITUTION_PROPORTION * Array::size) {} + SubstitutionArray(const SubstitutionArray©) : + Array((const Array&)copy), + substitutions(copy.substitutions), + maximumSubstitutions(copy.maximumSubstitutions) {} + + SubstitutionArray&operator =(const Array©) { + Array::operator =(copy); + substitutions = NULL; + maximumSubstitutions = MAXIMUM_SUBSTITUTION_PROPORTION * Array::size; + return *this; + } + SubstitutionArray&operator =(const SubstitutionArray©) { + Array::operator =((const Array&)copy); + substitutions = copy.substitutions; + maximumSubstitutions = MAXIMUM_SUBSTITUTION_PROPORTION * Array::size; + return *this; + } + + unsigned getSize() const { + return Array::getSize(); + } + + class Entry { + protected: + SubstitutionArray& owner; + unsigned index; + public: + Entry(const SubstitutionArray&owner, unsigned index) : + owner(const_cast(owner)), + index(index) {} + + operator T() const { + if (owner.substitutions) { + std::map::const_iterator substitution = + owner.substitutions->find(index); + if (substitution != owner.substitutions->end()) { + return substitution->second; + } + } + return owner.array[index]; + } + + Entry&operator =(const T&value) { + if (*owner.referenceCount > 1) { + if (!owner.substitutions) { + owner.substitutions = new std::map(); + } + (*owner.substitutions)[index] = value; + owner.autoFinalizeSubstitutions(); + } else { + owner.array[index] = value; + } + return *this; + } + + Entry&operator --() { + T old = operator T(); + return operator =(--old); + } + Entry&operator ++() { + T old = operator T(); + return operator =(++old); + } + }; + + const Entry operator[](unsigned index) const { + return Entry(*this, index); + } + Entry operator[](unsigned index) { + return Entry(*this, index); + } + + void fill(const T&filler) { + if (*Array::referenceCount > 1) { + Array::destroy(); + Array::array = new T[Array::size]; + Array::referenceCount = new unsigned(1); + substitutions = NULL; + } + Array::fill(filler); + } + + void finalizeSubstitutions() { + if (!substitutions) { + return; + } + T*replacement = new T[Array::size]; + for (unsigned i = Array::size; i--;) { + replacement[i] = Array::array[i]; + } + for (typename std::map::const_iterator iterator = + substitutions->begin(), + end = substitutions->end(); + iterator != end; ++iterator) { + replacement[iterator->first] = iterator->second; + } + Array::destroy(); + Array::array = replacement; + Array::referenceCount = new unsigned(1); + substitutions->clear(); + } + + void autoFinalizeSubstitutions(){ + if (substitutions && substitutions->size() > maximumSubstitutions) { + finalizeSubstitutions(); + } + } +}; + +templatestd::ostream&operator << + (std::ostream&out, const SubstitutionArray&array) { + out << '['; + for (unsigned i = 0; i < array.getSize(); ++i) { + out << array[i] << ','; + } + return out << "X]"; +} + +template > + class SubstitutionArrayComparator { +public: + bool operator()(const Array&left,const Array&right) { + static COMPARE compare; + unsigned leftSize = left.getSize(); + unsigned rightSize = right.getSize(); + if (leftSize < rightSize) { + return true; + } + if (leftSize > rightSize) { + return false; + } + for (unsigned i = 0; i < leftSize; ++i) { + if (compare(left[i], right[i])) { + return true; + } + if (compare(right[i], left[i])) { + return false; + } + } + return false; + } +}; + +#endif -- cgit v1.2.1