1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 1d9faf38de Squashed 'software/gecode/' content from commit 313e8764
git-subtree-dir: software/gecode
git-subtree-split: 313e87646da4fc2752a70e83df16d993121a8e40
2021-06-16 14:02:33 +10:00

379 lines
10 KiB
C++
Executable File

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
* Guido Tack <tack@gecode.org>
*
* Contributing authors:
* Gregory Crosswhite <gcross@phys.washington.edu>
*
* Copyright:
* Gregory Crosswhite, 2011
* Christian Schulte, 2003
* Guido Tack, 2004
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <iostream>
#include <sstream>
namespace Gecode {
/**
* \brief Shared array with arbitrary number of elements
*
* Sharing is implemented by reference counting: the same elements
* are shared among several objects.
*
*/
template<class T>
class SharedArray : public SharedHandle {
protected:
/// Implementation of object for shared arrays
class SAO : public SharedHandle::Object {
private:
/// Elements
T* a;
/// Number of elements
int n;
public:
/// Allocate for \a n elements
SAO(int n);
/// Delete object
virtual ~SAO(void);
/// Access element at position \a i
T& operator [](int i);
/// Access element at position \a i
const T& operator [](int i) const;
/// Return number of elements
int size(void) const;
/// Return beginning of array (for iterators)
T* begin(void);
/// Return beginning of array (for iterators)
const T* begin(void) const;
/// Return end of array (for iterators)
T* end(void);
/// Return end of array (for iterators)
const T* end(void) const;
};
public:
/// \name Associated types
//@{
/// Type of the view stored in this array
typedef T value_type;
/// Type of a reference to the value type
typedef T& reference;
/// Type of a constant reference to the value type
typedef const T& const_reference;
/// Type of a pointer to the value type
typedef T* pointer;
/// Type of a read-only pointer to the value type
typedef const T* const_pointer;
/// Type of the iterator used to iterate through this array's elements
typedef T* iterator;
/// Type of the iterator used to iterate read-only through this array's elements
typedef const T* const_iterator;
/// Type of the iterator used to iterate backwards through this array's elements
typedef std::reverse_iterator<T*> reverse_iterator;
/// Type of the iterator used to iterate backwards and read-only through this array's elements
typedef std::reverse_iterator<const T*> const_reverse_iterator;
//@}
/**
* \brief Construct as not yet intialized
*
* The only member functions that can be used on a constructed but not
* yet initialized shared array is init and the assignment operator .
*
*/
SharedArray(void);
/// Initialize as array with \a n elements
SharedArray(int n);
/**
* \brief Initialize as array with \a n elements
*
* This member function can only be used once and only if the shared
* array has been constructed with the default constructor.
*
*/
void init(int n);
/// Initialize from shared array \a a (share elements)
SharedArray(const SharedArray& a);
/// Initialize from argument array \a a
SharedArray(const ArgArrayBase<T>& a);
/// Access element at position \a i
T& operator [](int i);
/// Access element at position \a i
const T& operator [](int i) const;
/// Return number of elements
int size(void) const;
/// Test equality with \a sa
bool operator ==(const SharedArray<T>& sa) const;
/// \name Array iteration
//@{
/// Return an iterator at the beginning of the array
iterator begin(void);
/// Return a read-only iterator at the beginning of the array
const_iterator begin(void) const;
/// Return an iterator past the end of the array
iterator end(void);
/// Return a read-only iterator past the end of the array
const_iterator end(void) const;
/// Return a reverse iterator at the end of the array
reverse_iterator rbegin(void);
/// Return a reverse and read-only iterator at the end of the array
const_reverse_iterator rbegin(void) const;
/// Return a reverse iterator past the beginning of the array
reverse_iterator rend(void);
/// Return a reverse and read-only iterator past the beginning of the array
const_reverse_iterator rend(void) const;
//@}
};
/**
* \brief Print array elements enclosed in curly brackets
* \relates SharedArray
*/
template<class Char, class Traits, class T>
std::basic_ostream<Char,Traits>&
operator <<(std::basic_ostream<Char,Traits>& os,
const SharedArray<T>& x);
/*
* Implementation
*
*/
/*
* Shared arrays
*
*/
template<class T>
forceinline
SharedArray<T>::SAO::SAO(int n0) : n(n0) {
a = (n>0) ? heap.alloc<T>(n) : nullptr;
}
template<class T>
SharedArray<T>::SAO::~SAO(void) {
if (n>0) {
heap.free<T>(a,n);
}
}
template<class T>
forceinline T&
SharedArray<T>::SAO::operator [](int i) {
assert((i>=0) && (i<n));
return a[i];
}
template<class T>
forceinline const T&
SharedArray<T>::SAO::operator [](int i) const {
assert((i>=0) && (i<n));
return a[i];
}
template<class T>
forceinline int
SharedArray<T>::SAO::size(void) const {
return n;
}
template<class T>
forceinline T*
SharedArray<T>::SAO::begin(void) {
return a;
}
template<class T>
forceinline const T*
SharedArray<T>::SAO::begin(void) const {
return a;
}
template<class T>
forceinline T*
SharedArray<T>::SAO::end(void) {
return a+n;
}
template<class T>
forceinline const T*
SharedArray<T>::SAO::end(void) const {
return a+n;
}
template<class T>
forceinline
SharedArray<T>::SharedArray(void) {}
template<class T>
forceinline
SharedArray<T>::SharedArray(int n)
: SharedHandle(new SAO(n)) {}
template<class T>
forceinline
SharedArray<T>::SharedArray(const SharedArray<T>& sa)
: SharedHandle(sa) {}
template<class T>
forceinline void
SharedArray<T>::init(int n) {
assert(object() == nullptr);
object(new SAO(n));
}
template<class T>
forceinline T&
SharedArray<T>::operator [](int i) {
assert(object() != nullptr);
return (*static_cast<SAO*>(object()))[i];
}
template<class T>
forceinline const T&
SharedArray<T>::operator [](int i) const {
assert(object() != nullptr);
return (*static_cast<SAO*>(object()))[i];
}
template<class T>
inline bool
SharedArray<T>::operator ==(const SharedArray<T>& sa) const {
if (size() != sa.size())
return false;
if (object()==sa.object())
return true;
for (int i=0; i<size(); i++) {
if ((*this)[i] != sa[i])
return false;
}
return true;
}
template<class T>
forceinline
SharedArray<T>::SharedArray(const ArgArrayBase<T>& a)
: SharedHandle(new SAO(a.size())) {
for (int i=0; i<a.size(); i++)
operator [](i)=a[i];
}
template<class T>
forceinline int
SharedArray<T>::size(void) const {
assert(object() != nullptr);
return static_cast<SAO*>(object())->size();
}
template<class T>
forceinline typename SharedArray<T>::iterator
SharedArray<T>::begin(void) {
assert(object() != nullptr);
return static_cast<SAO*>(object())->begin();
}
template<class T>
forceinline typename SharedArray<T>::const_iterator
SharedArray<T>::begin(void) const {
assert(object() != nullptr);
return static_cast<SAO*>(object())->begin();
}
template<class T>
forceinline typename SharedArray<T>::iterator
SharedArray<T>::end(void) {
assert(object() != nullptr);
return static_cast<SAO*>(object())->end();
}
template<class T>
forceinline typename SharedArray<T>::const_iterator
SharedArray<T>::end(void) const {
assert(object() != nullptr);
return static_cast<SAO*>(object())->end();
}
template<class T>
forceinline typename SharedArray<T>::reverse_iterator
SharedArray<T>::rbegin(void) {
assert(object() != nullptr);
return reverse_iterator(static_cast<SAO*>(object())->end());
}
template<class T>
forceinline typename SharedArray<T>::const_reverse_iterator
SharedArray<T>::rbegin(void) const {
assert(object() != nullptr);
return const_reverse_iterator(static_cast<SAO*>(object())->end());
}
template<class T>
forceinline typename SharedArray<T>::reverse_iterator
SharedArray<T>::rend(void) {
assert(object() != nullptr);
return reverse_iterator(static_cast<SAO*>(object())->begin());
}
template<class T>
forceinline typename SharedArray<T>::const_reverse_iterator
SharedArray<T>::rend(void) const {
assert(object() != nullptr);
return const_reverse_iterator(static_cast<SAO*>(object())->begin());
}
template<class Char, class Traits, class T>
std::basic_ostream<Char,Traits>&
operator <<(std::basic_ostream<Char,Traits>& os,
const SharedArray<T>& x) {
std::basic_ostringstream<Char,Traits> s;
s.copyfmt(os); s.width(0);
s << '{';
if (x.size() > 0) {
s << x[0];
for (int i=1; i<x.size(); i++)
s << ", " << x[i];
}
s << '}';
return os << s.str();
}
}
// STATISTICS: kernel-other