/* -*- 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 #include /** * \namespace Gecode::Reflection * \brief %Reflection support */ namespace Gecode { namespace Reflection { /** \addtogroup TaskReflection * @{ */ /// Exception for errors during reflection class GECODE_VTABLE_EXPORT ReflectionException : public Exception { public: /// Constructor ReflectionException(const char* what) : Exception("Reflection", what) {} }; /// Exception: no reflection defined class GECODE_VTABLE_EXPORT NoReflectionDefinedException : public ReflectionException { public: NoReflectionDefinedException(void) : ReflectionException("No reflection defined") {} }; //@} class ArrayArg; class IntArrayArg; /** * \brief Arguments for actor and variable specifications * * These arguments implement a simple term language. A term is * an integer, a variable, an array of terms, an array of integers, * a string, a pair, a shared object, or a reference to a shared object. * * Variables are represented by integers that correspond to indices in a * VarMap. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT Arg { protected: /// The different types of arguments enum argtype { INT_ARG, ///< Integer argument VAR_ARG, ///< Variable argument ARRAY_ARG, ///< Array argument INT_ARRAY_ARG, ///< Integer array argument STRING_ARG, ///< String argument PAIR_ARG, ///< Pair argument SHARED_OBJECT_ARG, ///< Shared object argument SHARED_REF_ARG ///< Reference to shared object argument }; /// Argument type of this Arg argtype t; union { /// The integer of an INT_ARG, the index of a VAR_ARG or SHARED_REF_ARG, or the size of an ARRAY_ARG or INT_ARRAY_ARG int i; /// The string of a STRING_ARG char* s; /// The first argument of a PAIR_ARG, or the object of a SHARED_OBJECT_ARG Arg* first; } arg1; union { /// The second argument of a PAIR_ARG Arg* second; /// The array of an ARRAY_ARG Arg** aa; /// The array of an INT_ARRAY_ARG int* ia; } arg2; /// Constructor Arg(argtype t); public: /// %Test if this represents an integer bool isInt(void) const; /// Return the integer that this argument represents int toInt(void) const; /// Create new int argument static Arg* newInt(int i); /// Initialize this as an int argument void initInt(int i); /// %Test if this represents a variable bool isVar(void) const; /// Return the variable index that this argument represents int toVar(void) const; /// Create new variable argument static Arg* newVar(int i); /// Initialize this as a variable argument void initVar(int i); /// %Test if this represents an array bool isArray(void) const; /// Return the array that this argument represents ArrayArg* toArray(void); /// Return the array that this argument represents const ArrayArg* toArray(void) const; /// Create new array argument with size \a n static ArrayArg* newArray(int n); /// Initialize this as an array argument with size \a n void initArray(int n); /// %Test if this represents an array bool isIntArray(void) const; /// Return the array that this argument represents IntArrayArg* toIntArray(void); /// Return the array that this argument represents const IntArrayArg* toIntArray(void) const; /// Create new integer array argument with size \a n static IntArrayArg* newIntArray(int n); /// Create new integer array argument from array \a a template static IntArrayArg* newIntArray(const A& a); /// Initialize this as an int array argument with size \a n void initIntArray(int n); /// %Test if this represents a string bool isString(void) const; /// Return the string that this argument represents const char* toString(void) const; /// Create new string argument static Arg* newString(const char* s); /// Initialize this as a string argument void initString(const char* s); /// %Test if this represents a pair bool isPair(void) const; /// Return the first component of the pair that this argument represents Arg* first(void); /// Return the first component of the pair that this argument represents const Arg* first(void) const; /// Return the second component of the pair that this argument represents Arg* second(void); /// Return the second component of the pair that this argument represents const Arg* second(void) const; /// Create new pair argument from \a a and \a b static Arg* newPair(Arg* a, Arg* b); /// Initialize this as a pair argument from \a a and \a b void initPair(Arg* a, Arg* b); /// %Test if this represents a shared object bool isSharedObject(void) const; /// Return the shared object that this argument represents Arg* toSharedObject(void); /// Return the shared object that this argument represents const Arg* toSharedObject(void) const; /// Create new shared object static Arg* newSharedObject(Arg* a); /// Initialize this as a shared object void initSharedObject(Arg* a); /// %Test if this represents a shared object reference bool isSharedReference(void) const; /// Return the shared object that this argument represents int toSharedReference(void) const; /// Create new reference to shared object static Arg* newSharedReference(int ref); /// Initialize this as a reference to a shared object void initSharedReference(int ref); /// Destructor GECODE_MSC_VIRTUAL ~Arg(void); }; /** * \brief Array arguments * * This is a convenience class that exposes an array interface * for an Arg that was created via Arg::newArray. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT ArrayArg : public Arg { private: /// Use Arg::newArray instead ArrayArg(void); public: /// Element access const Arg* operator[](int i) const; /// Element access Arg*& operator[](int i); /// Size of the array int size(void) const; }; /** * \brief Integer array arguments * * This is a convenience class that exposes an array interface * for an Arg that was created via Arg::newIntArray. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT IntArrayArg : public Arg { private: /// Use Arg::newIntArray instead IntArrayArg(void); public: /// Element access const int& operator[](int i) const; /// Element access int& operator[](int i); /// Size of the array int size(void) const; }; /** * \brief Iterate over an IntArrayArg, interpreting consecutive * pairs of integers as ranges * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT IntArrayArgRanges { private: /// The array Reflection::IntArrayArg* a; /// The current position int n; public: /// Constructor IntArrayArgRanges(Reflection::IntArrayArg* a0); /// %Test whether iterator is still at a valid range bool operator()(void); /// Move iterator to next range void operator++(void); /// Minimum of current range int min(void) const; /// Maximum of current range int max(void) const; /// Width of current range unsigned int width(void) const; }; /** * \brief %Variable specification * * A VarSpec contains an abstract specification of a variable * implementation. These specifications are typically stored in a VarMap. * * The type of the variable is represented as a Symbol and called vti * (variable type identifier). In order to find out what type of variable a * VarSpec corresponds to, you can compare the vti with VarImp::vti of a * concrete variable type (e.g. IntVarImp::vti). * * The domain of a variable is represented as an Arg. The concrete encoding * depends on the variable type. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT VarSpec { private: class Domain; /// A representation of the domain of this variable Domain* _dom; public: /// Construct empty VarSpec VarSpec(void); /// Construct specification for a variable VarSpec(Support::Symbol vti, Arg* domain, bool assigned=false); /// Copy constructor VarSpec(const VarSpec& s); /// Assignment operator const VarSpec& operator=(const VarSpec& s); /// Destructor GECODE_MSC_VIRTUAL ~VarSpec(void); /// Set the name for this variable void name(const Support::Symbol& n0); /// Get the name of this variable Support::Symbol name(void) const; /// Return if variable has a name bool hasName(void) const; /// Get the domain of this variable Arg* dom(void) const; /// Return whether variable is assigned bool assigned(void) const; // Get the variable type identifier for this variable Support::Symbol vti(void) const; }; /** * \brief %Actor specification * * An ActorSpec contains all the information that characterizes an Actor. * The specifications for all the actors in a Space object can be accessed * using an ActorSpecIter. * * Each ActorSpec describes either a Branching or a Propagator * (reflected by ActorSpec::isBranching). As a user of the Reflection API, * you can access the information describing an Actor as an array of * arguments, represented as objects of the Arg class. * * Every propagator and branching must be able to return a specification * through the virtual function Actor::spec. If you use one of the * convenience classes like BinaryPropagator, have a look at the * implementation of AbsBnd::spec. If you subclass Propagator directly, or * you have additional arguments that have to be put into the ActorSpec, * please look at BinaryPropagator::spec. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT ActorSpec { friend class BranchingSpec; private: class Arguments; /// The arguments of this actor Arguments* _args; /// Resize argument array void resize(void); friend class ActorSpecIter; /// Set the queue of the actor to \a q void queue(int q); /** \brief Return identifier of the branching * Only valid if isBranching returns true */ unsigned int branchingId(void) const; public: /// Construct empty ActorSpec ActorSpec(void); /// Construct actor specification with \a name ActorSpec(const Support::Symbol& name); /// Copy constructor ActorSpec(const ActorSpec& s); /// Assignment operator const ActorSpec& operator=(const ActorSpec& s); /// Destructor GECODE_MSC_VIRTUAL ~ActorSpec(void); /// \name Actor information //@{ /// Return actor type identifier Support::Symbol ati(void) const; /// Return number of arguments int noOfArgs(void) const; /// Check that the number of arguments is \a n, throw exception otherwise void checkArity(int n) const; /// Return argument \a i Arg* operator[](int i) const; /// Return whether the actor is a branching bool isBranching(void) const; /** \brief Return queue where the actor is currently scheduled * Only valid if isBranching returns false */ int queue(void) const; //@} /// \name Populating the specification //@{ /// Add \a arg to the specification (as last argument) void add(Arg* arg); //@} }; }} /** \brief Add \a a to specification * \relates Gecode::Reflection::ActorSpec */ Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, Gecode::Reflection::Arg* arg); /** \brief Add \a i to specification * \relates Gecode::Reflection::ActorSpec */ Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, int i); /** \brief Add \a i to specification * \relates Gecode::Reflection::ActorSpec */ Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, unsigned int i); /** \brief Add \a d to specification, where \a d is cast into an integer * \relates Gecode::Reflection::ActorSpec */ Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, double i); /* Implementation of ActorSpec operators */ forceinline Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, Gecode::Reflection::Arg* arg) { s.add(arg); return s; } forceinline Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, int i) { return s << Gecode::Reflection::Arg::newInt(i); } forceinline Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, unsigned int i) { return s << Gecode::Reflection::Arg::newInt(static_cast(i)); } forceinline Gecode::Reflection::ActorSpec operator<<(Gecode::Reflection::ActorSpec s, double i) { return s << Gecode::Reflection::Arg::newInt(static_cast(i)); } namespace Gecode { namespace Reflection { /** * \brief %Branching specification * * A BranchingSpec contains information about the alternatives of a Space. * It is similar to a BranchingDesc, but not opaque: you can query the * information. * * The specification for an alternative is an ArrayArg that may contain * strings and references to variables. The concatenation of the strings * and variables is a human-readable description of what constraints are * posted for the given alternative. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT BranchingSpec { private: class Arguments; /// The arguments of this branching Arguments* _args; public: /// Default constructor BranchingSpec(void); /** \brief Construct spec for branching description \a d * * This constructor is used by a Branching to create a BranchingSpec. * As a user of the reflection API, you have to query use the function * Gecode::Space::branchingSpec instead. * */ BranchingSpec(const BranchingDesc* d); /// Copy constructor BranchingSpec(const BranchingSpec& s); /// Assignment operator const BranchingSpec& operator=(const BranchingSpec& s); /// Destructor GECODE_MSC_VIRTUAL ~BranchingSpec(void); ///\name Branching information //@{ /// Check if specification was created by \a b bool createdBy(const ActorSpec& b) const; /// Return number of alternatives unsigned int alternatives(void) const; /// Return specification of alternative \a i Arg* operator[](int i) const; /// Return specification of alternative \a i Arg*& operator[](int i); //@} }; class VarMap; /** * \brief Iterating actor specifications * * Use this iterator to access specifications of all actors (propagators * and branchings) of a space. The iterator also provides access to the * corresponding variable map. * * \ingroup TaskReflection */ class GECODE_KERNEL_EXPORT ActorSpecIter { private: /// The variable map used by this iterator VarMap* m; /// The space for which to iterate the actors const Space* s; /// The queue to iterate const ActorLink *active; /// The current actor const ActorLink *cur; /// Whether the current actor is a branching bool isBranching; public: /// Constructor ActorSpecIter(const Space*, VarMap&); /// %Test whether iterator still has actor specifications or is done bool operator()(void) const; /// Move iterator to next actor void operator++(void); /// Return actor specification for current iterator position ActorSpec actor(void) const; }; /** * \brief Registry of constraint posting and variable creation functions * \ingroup TaskReflection */ class Registry { private: class RegistryObject; RegistryObject* ro; public: /// The type of constraint posting functions typedef void (*poster) (Space*, VarMap&, const ActorSpec&); /// The type of variable creation functions typedef VarImpBase* (*varCreator) (Space*, VarSpec&); /// The type of variable domain constraint functions typedef void (*varConstrainer) (Space*, VarImpBase*, VarSpec&); /// The type of variable update functions typedef VarImpBase* (*varUpdater) (Space*, bool, VarImpBase*); /// The type of variable printing functions typedef std::ostream& (*varPrinter) (std::ostream&, VarImpBase*); /// The type of variable reflection functions typedef Arg* (*varSpec) (const Space* home, VarMap& m, VarImpBase*); /// Constructor GECODE_KERNEL_EXPORT Registry(void); /// Destructor GECODE_KERNEL_EXPORT GECODE_MSC_VIRTUAL ~Registry(void); /// Create a new variable in \a home from \a spec and return it GECODE_KERNEL_EXPORT VarImpBase* createVar(Space* home, VarSpec& spec) const; /// Constrain \a v to \a spec GECODE_KERNEL_EXPORT void constrainVar(Space* home, VarImpBase* v, VarSpec& spec) const; /// Update variable \a v with type identifier \a vti during cloning GECODE_KERNEL_EXPORT VarImpBase* updateVariable(Space* home, bool share, VarImpBase* v, const Support::Symbol& vti) const; /// Print variable \a v with type identifier \a vti to \a os GECODE_KERNEL_EXPORT std::ostream& printVariable(std::ostream& os, VarImpBase* v, const Support::Symbol& vti) const; /// Reflection for variable \a v with type identifier \a vti GECODE_KERNEL_EXPORT Arg* spec(const Space* home, VarMap& vm, VarImpBase* v, const Support::Symbol& vti) const; /// Post constraint in \a home for \a spec using variables \a vars GECODE_KERNEL_EXPORT void post(Space* home, VarMap& vm, const ActorSpec& spec) const; /// Register variable creation function for \a vti GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varCreator vc); /// Register variable domain constraining function for \a vti GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varConstrainer vc); /// Register variable update function for \a vti GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varUpdater vu); /// Register variable print function for \a vti GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varPrinter vp); /// Register variable reflection function for \a vti GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varSpec vp); /// Register constraint posting function for actor type identifier \a ati GECODE_KERNEL_EXPORT void add(const Support::Symbol& ati, poster p); /// Print list of all registered posters to \a out GECODE_KERNEL_EXPORT void print(std::ostream& out); private: /// Do not allow copying Registry(const Registry&); /// Do not allow assignment Registry& operator=(const Registry&); }; /// The registry object \ingroup TaskReflection GECODE_KERNEL_EXPORT Registry& registry(void); /** \brief Class used for registering actors * * \ingroup TaskReflection * * The registered Actor class \a P has to provide two functions: * - static Support::Symbol ati(void) * - static void post(Space*, const VarMap&, const ActorSpec&) */ template class ActorRegistrar { public: /// Default constructor ActorRegistrar(void); }; template ActorRegistrar

::ActorRegistrar(void) { registry().add(P::ati(), &P::post); } /** \brief Class used for registering variable implementations * * \ingroup TaskReflection * * The registered variable implementation class \a V has to * provide two functions: * - static void create(Space*, Reflection::VarSpec&) * - static void contrain(Space*, VarImpBase*, Reflection::VarSpec&) */ template class VarImpRegistrar { private: static VarImpBase* updateVar(Space* home, bool share, VarImpBase* v); static std::ostream& printVar(std::ostream& os, VarImpBase* v); static Reflection::Arg* spec(const Space* home, Reflection::VarMap& m, VarImpBase* v); public: /// Default constructor VarImpRegistrar(void); }; template VarImpBase* VarImpRegistrar::updateVar(Space* home, bool share, VarImpBase* v) { typedef typename VarImpVarTraits::Var Var; typedef typename VarViewTraits::View View; View view(static_cast(v)); Var var(view); Var varCopy; varCopy.update(home, share, var); View viewCopy(varCopy); return viewCopy.var(); } template std::ostream& VarImpRegistrar::printVar(std::ostream& os, VarImpBase* v) { typedef typename VarImpVarTraits::Var Var; typedef typename VarViewTraits::View View; View view(static_cast(v)); Var var(view); return os << var; } template Reflection::Arg* VarImpRegistrar::spec(const Space* home, Reflection::VarMap& m, VarImpBase* v) { typedef typename VarImpVarTraits::Var Var; typedef typename VarViewTraits::View View; View view(static_cast(v)); return view.spec(home, m); } template VarImpRegistrar::VarImpRegistrar(void) { registry().add(V::vti, &V::create); registry().add(V::vti, &V::constrain); registry().add(V::vti, &VarImpRegistrar::updateVar); registry().add(V::vti, &VarImpRegistrar::printVar); registry().add(V::vti, &VarImpRegistrar::spec); } /** * \brief Generic variables * * \ingroup TaskReflection * * A generic variable can represent any Gecode variable. It can be * used in VarArrays, and it supports generic update during cloning. * */ class Var { private: /// The actual variable VarImpBase* _var; /// The variable type identifier Support::Symbol _vti; public: /// Default constructor Var(void); /// Construct from \a v template explicit Var(const VarBase& v); /// Construct from \a v Var(const Var& v); /// Construct from \a var with variable type identifier \a vti Var(VarImpBase* var, const Support::Symbol& vti); /// Update during cloning GECODE_KERNEL_EXPORT void update(Space* home, bool share, Var& v); /// Output to \a os GECODE_KERNEL_EXPORT std::ostream& print(std::ostream& os) const; /// Reflection GECODE_KERNEL_EXPORT Arg* spec(const Space* home, VarMap& vm) const; /// Cast to variable implementation base VarImpBase* varImpBase(void) const; /// Cast to concrete variable type template VarImp* var(void) const; }; /** * \brief Unreflection from VarSpec and ActorSpec * \ingroup TaskReflection * * An Unreflector allows you to install variables and propagators in a * Space using variable and actor specifications. * */ class GECODE_KERNEL_EXPORT Unreflector { private: /// The space in which to create variables and post constraints Space* home; /// The VarMap that indicates which variables to reuse Reflection::VarMap& m; public: /// Constructor Unreflector(Space* home0, Reflection::VarMap& m0); /// Destructor GECODE_MSC_VIRTUAL ~Unreflector(void); /// Return the VarMap Reflection::VarMap& varMap(void) const; /// Create a new variable from \a spec void var(Reflection::VarSpec& spec); /// Post the constraint defined by \a spec void post(Reflection::ActorSpec& spec); }; forceinline Var::Var(void) {} template forceinline Var::Var(const VarBase& v) { _var = v.var(); _vti = v.var()->vti; } forceinline Var::Var(const Var& v) : _var(v._var), _vti(v._vti) {} forceinline Var::Var(VarImpBase* var, const Support::Symbol& vti) : _var(var), _vti(vti) {} forceinline VarImpBase* Var::varImpBase(void) const { return static_cast(_var); } template inline VarImp* Var::var(void) const { if (! (VarImp::vti == _vti)) throw ReflectionException("VTI mismatch"); return static_cast(_var); } /** \addtogroup TaskReflection * @{ */ /// Register a propagator with zero or one template argument #define GECODE_REGISTER1(P) \ ::Gecode::Reflection::ActorRegistrar< P > GECODE_FRESH(r) /// Register a propagator with two template arguments #define GECODE_REGISTER2(P1,P2) \ ::Gecode::Reflection::ActorRegistrar< P1,P2 > GECODE_FRESH(r) /// Register a propagator with three template arguments #define GECODE_REGISTER3(P1,P2,P3) \ ::Gecode::Reflection::ActorRegistrar< P1,P2,P3 > GECODE_FRESH(r) /// Register a propagator with four template arguments #define GECODE_REGISTER4(P1,P2,P3,P4) \ ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4 > GECODE_FRESH(r) /// Register a propagator with five template arguments #define GECODE_REGISTER5(P1,P2,P3,P4,P5) \ ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4,P5 > GECODE_FRESH(r) /// Register a propagator with six template arguments #define GECODE_REGISTER6(P1,P2,P3,P4,P5,P6) \ ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4,P5,P6 > GECODE_FRESH(r) //@} /************************************** * Implementations **************************************/ template IntArrayArg* Arg::newIntArray(const A& a) { IntArrayArg* ret = Arg::newIntArray(a.size()); for (int i=a.size(); i--;) (*ret)[i] = a[i]; return ret; } /** \addtogroup TaskReflection * @{ */ /** \brief String representation for View types, used for name mangling */ template class TypeOf { public: /// Return string representation static Support::Symbol t(void) { return View::type(); } }; /** \brief String representation for bool, used for name mangling */ template <> class TypeOf { public: /// Return string representation static Support::Symbol t(void) { return Support::Symbol("bool"); } }; /** \brief String representation for ints, used for name mangling */ template <> class TypeOf { public: /// Return string representation static Support::Symbol t(void) { return Support::Symbol("int"); } }; /** \brief String representation for doubles, used for name mangling */ template <> class TypeOf { public: /// Return string representation static Support::Symbol t(void) { return Support::Symbol("double"); } }; //@} } class IntSet; namespace Reflection { /** \addtogroup TaskReflection * @{ */ /** \brief String representation for IntSets, used for name mangling */ template <> class TypeOf { public: /// Return string representation static Support::Symbol t(void) { return Support::Symbol("IntSet"); } }; /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, bool b) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(b); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, unsigned int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, bool b) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(b); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, unsigned int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, bool b) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(b); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, unsigned int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, bool b) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(b); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, unsigned int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, bool b) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(b); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } /// Mangle ati with type information template Support::Symbol mangle(const Support::Symbol& ati, unsigned int i) { Support::Symbol mangled = ati.copy(); mangled += "<"; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += TypeOf::t(); mangled += ","; mangled += Support::Symbol(i); mangled += ">"; return mangled; } //@} }} /// Print \a v to \a os GECODE_KERNEL_EXPORT std::ostream& operator<<(std::ostream& os, const Gecode::Reflection::Var& v); // STATISTICS: kernel-other