/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack * * Copyright: * Guido Tack, 2007 * * Last modified: * $Date: 2008-07-11 09:39:08 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $ * $Revision: 7297 $ * * 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 namespace Gecode { namespace Reflection { class VarMapIter; /** * \brief Mapping %Gecode variable implementations to variable specifications * * The reflection API always references variables by indices into a VarMap. * The VarMap is filled with information when you access the specification * of a propagator. If, for instance, a propagator references some * IntVarImp, and that particular variable implementation is already * contained in the VarMap, the ActorSpec for the propagator will contain a * reference to the index of the variable implementation. If it is not * already in the VarMap, its VarSpec is extracted, and the variable * implementation is put in the map. The ActorSpec then of course * references the newly created index. * * A VarMap also maps variable implementations to names. The names can be * assigned in the script, using the virtual function Space::getVars (see * Queens as an example). That way, the variables mentioned in an ActorSpec * can be identified with variables from the model. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT VarMap { friend class VarMapIter; private: class VarMapObj; VarMapObj* vo; public: /// Default constructor VarMap(void); /// Copy constructor VarMap(const VarMap&); /// Assignment operator VarMap& operator=(const VarMap&); /// Destructor GECODE_MSC_VIRTUAL ~VarMap(void); /// Return number of entries int size(void) const; /// Return index for variable implementation \a x int index(const VarImpBase* x) const; /// Return index for variable implementation with name \a n int index(const Support::Symbol& n) const; /// Return if variable implementation with name \a n is known bool nameIsKnown(const Support::Symbol& n) const; /// Return if variable implementation \a x has a name bool hasName(const VarImpBase* x) const; /// Return if variable implementation at index \a i has a name bool hasName(int i) const; /// Return name for variable implementation \a x Support::Symbol name(const VarImpBase* x) const; /// Return name for variable implementation at index \a i Support::Symbol name(int i) const; /// Return variable implementation with name \a n VarImpBase* varImpBase(const Support::Symbol& n) const; /// Return variable implementation at index \a i VarImpBase* varImpBase(int i) const; /// Return variable with name \a n Var var(const Support::Symbol& n) const; /// Return variable at index \a i Var var(int i) const; /// Return specification for variable implementation \a x VarSpec& spec(const VarImpBase* x) const; /// Return specification for variable implementation at index \a i VarSpec& spec(int i) const; /// Return specification for variable implementation with name \a n VarSpec& spec(const Support::Symbol& n) const; /// Register name \a n for variable implementation \a x void name(VarImpBase* x, const Support::Symbol& n); /// Insert specification \a vs for variable implementation \a x, return index int put(const VarImpBase* x, VarSpec* vs); /// Insert a shared object into the table void putMasterObject(void* obj); /// Get the index of a shared object from the table int getSharedIndex(void* obj) const; /// Get the shared object stored at index \a i void* getSharedObject(int i) const; /// \name Interface for modeling //@{ /// Insert specification for variable \a v with name \a n template void put(const Space* home, const Var& v, const Support::Symbol& n, bool registerOnly = false); /// Insert specifications for variables in \a x with name \a n template void putArray(const Space* home, const VarArgArray& v, const Support::Symbol& n, bool registerOnly = false); /// Insert specifications for variables in \a x with name \a n template void putArray(const Space* home, const VarArray& v, const Support::Symbol& n, bool registerOnly = false); //@} }; /** * \brief Iterating a variable map * * The variable map is filled dynamically while iterating over the * actors of a space. The iterator will signal that it is done when all * currently known variables have been iterated, but it will later become * available again once new variables are encountered. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT VarMapIter { private: /// The variable map to iterate VarMap* m; /// The current index int i; public: /// Construct iterator for variable map \a m VarMapIter(VarMap& m); /// Test whether iterator still has variables or is done bool operator()(void) const; /// Return variable specification for current iterator position VarSpec& spec(void) const; /// Return variable implementation for current iterator position VarImpBase* varImpBase(void) const; /// Return variable for current iterator position Var var(void) const; /// Move iterator to next variable void operator++(void); }; template <> void inline VarMap::put(const Space* home, const Reflection::Var& x, const Support::Symbol& n, bool registerOnly) { if (! (n == "")) name(x.varImpBase(), n); if (!registerOnly) { Reflection::Arg* a = x.spec(home, *this); delete a; } } template void VarMap::put(const Space* home, const V& x, const Support::Symbol& n, bool registerOnly) { typename VarViewTraits::View v(x); if (! (n == "")) name(v.var(), n); if (!registerOnly) { Reflection::Arg* a = v.spec(home, *this); delete a; } } template void VarMap::putArray(const Space* home, const VarArgArray& x, const Support::Symbol& n, bool registerOnly) { for (int i=0; i void VarMap::putArray(const Space* home, const VarArray& x, const Support::Symbol& n, bool registerOnly) { for (int i=0; i