/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack * * Contributing authors: * Christian Schulte * * Copyright: * Guido Tack, 2006 * Christian Schulte, 2007 * * Last modified: * $Date: 2008-02-26 11:08:59 +0100 (Tue, 26 Feb 2008) $ by $Author: tack $ * $Revision: 6312 $ * * 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. * */ namespace Gecode { /* * Operations for set expression code * */ forceinline SetExprCode::Stream::Stream(void) : n(0) {} forceinline void SetExprCode::Stream::add(int i) { is[n++] = i; } forceinline int SetExprCode::Stream::size(void) const { return n; } forceinline int SetExprCode::Stream::operator[](int i) const { return is[i]; } forceinline SetExprCode::SetExprCode(void) {} forceinline SetExprCode::SetExprCode(const SetExprCode::Stream& s) : c(s.size()) { for (int i=s.size(); i--; ) c[i]=s[i]; } forceinline SetExprCode::SetExprCode(const SetExprCode& sc) : c(sc.c) {} forceinline void SetExprCode::update(Space* home, bool share, SetExprCode& sc) { c.update(home, share, sc.c); } forceinline int SetExprCode::size(void) const { return c.size(); } forceinline int SetExprCode::operator[](int i) const { return c[i]; } /* * Operations for expressions * */ forceinline SetExpr::SetExpr(void) : ax(NULL), sign(1) {} } inline Gecode::SetExpr operator-(const Gecode::SetExpr& s) { return Gecode::SetExpr(s, -1); } inline Gecode::SetExpr operator||(const Gecode::SetExpr& s, const Gecode::SetExpr& t) { return Gecode::SetExpr(s, 1, Gecode::SetExpr::REL_UNION, t, 1); } inline Gecode::SetExpr operator&&(const Gecode::SetExpr& s, const Gecode::SetExpr& t) { return Gecode::SetExpr(s, 1, Gecode::SetExpr::REL_INTER, t, 1); } inline Gecode::SetExpr operator-(const Gecode::SetExpr& s, const Gecode::SetExpr& t) { return Gecode::SetExpr(s, 1, Gecode::SetExpr::REL_INTER, t, -1); } namespace Gecode { /** * \brief Range iterator for set expressions */ class SetExprRanges { private: /// Reference-counted range iterators with virtual member functions class Iter; /// The actual iterator Iter *i; const SetExprRanges& operator=(const SetExprRanges&); public: /// \name Constructors and destructor //@{ /// Copy constructor SetExprRanges(const SetExprRanges&); /** Initialize with the views \a x, a set expression \a s, * and a flag whether \a s is to be interpreted in a monotone or * anti-monotone way */ SetExprRanges(const ViewArray& x, SetExpr& s, bool monotone); /** Initialize with the views \a x, a set expression code \a c, * and a flag whether \a c is to be interpreted in a monotone or * anti-monotone way */ SetExprRanges(const ViewArray& x, const SetExprCode& s, bool monotone); /// Destructor ~SetExprRanges(void); //@} /// \name Iteration control //@{ /// Move iterator to next range (if possible) bool operator()(void); /// Test whether iterator is still at a range or done void operator++(void); //@} /// \name Range access //@{ /// Return smallest value of range int min(void) const; /// Return largest value of range int max(void) const; /// Return width of range (distance between minimum and maximum) unsigned int width(void) const; //@} }; /** * \brief Reference-counted range iterators with virtual member functions * */ class SetExprRanges::Iter { public: /// The actual iterator Gecode::Iter::Ranges::Virt::Iterator* i; /// Reference count int num; /// Construct from iterator Iter(Gecode::Iter::Ranges::Virt::Iterator*); /// Destructor ~Iter(void); /// Increment reference count void increment(void); /// Decrement reference count bool decrement(void); }; forceinline SetExprRanges::Iter::Iter(Gecode::Iter::Ranges::Virt::Iterator* i0) : i(i0), num(1) {} forceinline SetExprRanges::Iter::~Iter(void) { delete i; } forceinline void SetExprRanges::Iter::increment(void) { ++num; } forceinline bool SetExprRanges::Iter::decrement(void) { return --num==0; } forceinline SetExprRanges::SetExprRanges(const SetExprRanges& s) : i(s.i) { i->increment(); } forceinline SetExprRanges::~SetExprRanges(void) { if (i->decrement()) delete i; } forceinline bool SetExprRanges::operator()(void) { return (*(i->i))(); } forceinline void SetExprRanges::operator++(void) { ++(*(i->i)); } forceinline int SetExprRanges::min(void) const { return i->i->min(); } forceinline int SetExprRanges::max(void) const { return i->i->max(); } forceinline unsigned int SetExprRanges::width(void) const { return i->i->width(); } } // STATISTICS: set-prop