FRAMES NO FRAMES

Macro ILCREV

Definition file: ilsolver/basic.h
ILCREV(t)

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: