Overview | Group | Tree | Graph | Index | Concepts |
This macro defines a reversible class for pointers to objects of the
class indicated by its argument type
. The macro is currently
useful because the class IlcRevAny
is not
typed; the pointers in objects of that class are of type IlcInt
and thus give no indication of the type of objects
they point to. In future releases, this macro will be replaced by a class
template. Solver does not yet use templates because they are not yet
correctly supported by all C++ compilers.
This macro makes use of IlcRev
, the root class of the
reversible classes IlcRevAny
,
IlcRevBool
, IlcRevFloat
, and IlcRevInt
.
That is, IlcRev
is the base class in the macro. This class is
not intended for direct instantiation. In other words, you should not call
its constructors directly yourself. Here is its synopsis.
class IlcRev{ public: IlcRev(); IlcRev(IloSolver s); ~IlcRev(){} };
To see how the macro works, let's assume that T
is the name
of a class. Then the following statement creates a class of objects that
each behave as a reversible pointer to an object of class
T
.
ILCREV(T);
That statement defines the following class, IlcRevT
.
class IlcRevT : public IlcRev{ public: operator T * () const; T * operator ->() const; T * getValue() const; void setValue(IloSolver solver, T * value); }; IlcBool operator == (const IlcRevT& rev, T * cst); IlcBool operator == (T * cst, const IlcRevT& rev); IlcBool operator == (const IlcRevT& rev1, const IlcRevT& rev2); IlcBool operator != (const IlcRevT& rev, T * cst); IlcBool operator != (T * cst, const IlcRevT& rev); IlcBool operator != (const IlcRevT& rev1, const IlcRevT& rev2);
The operators and member functions of that class behave like those of the
class IlcRevInt
, with the exception of the operator
->
.
T* IlcRevT::operator ->() const;
This overloaded operator returns the address of the object pointed to by
the invoking object of IlcRevT
.
Example
Here's an example showing how to have a data member for which all modifications are reversible.
class Dummy; ILCREV(Dummy); class Dummy { IloSolver _s; IlcRevInt _data; // reversible IlcRevDummy _next; // reversible IlcInt _state; // not reversible public: Dummy(IloSolver s, IlcInt i, IlcInt state): _s(s),_data(i), _state(state){} ~Dummy(){} IlcInt getData() const { return _data; } void setData(IlcInt i) { _data.setValue(_s, i); } Dummy* getNext() const { return _next; } void setNext(Dummy* next) { _next.setValue(_s, next); } IlcInt getNextData() const; }; IlcInt Dummy::getNextData() const { if (_next) return _next->getData(); // uses overloaded -> }
The value of data members of that class will be restored automatically by
Solver when it backtracks because they have been defined with the reversible
classes, IlcRevInt
and IlcRevDummy
.
For more information, see the concepts State and Reversibility.
See Also: