# Label reference

In &Cpp; the custom labels are defined by defining your own class that inherits from Label (which is defined in

    sched/Label.h

). Like this small example from a unit test:

    class ForkingLabel : public Label
    {
    public:
    	ForkingLabel(Unit *unit, Onceref rtype, const string &name,
    			Onceref next) :
    		Label(unit, rtype, name),
    		next_(next)
    	{ }

    	virtual void execute(Rowop *arg) const
    	{
    		unit_->fork(next_->adopt(arg));
    	}

    	Autoref next_;
    };

The subclass needs to define its own execution method:

    virtual void execute(Rowop *arg) const;

The base class takes care of all the general execution mechanics, chaining etc. All you need to do in this method is perform your user-defined actions. By the way, this method is protected and should never be called directly. The labels must always be called through a unit, which will then execute them in the correct way.

The subclass may (though doesn't have to) also define the custom clearing method:

    virtual void clearSubclass();

Currently this method is called by the public method

    clear()

after the label is marked as cleared but before clearing of the chain (though this order may change in the future).

The base class constructor is also protected, it's always constructed from a subclass. You can not instantiate the base Label class because it contains an abstract

    execute()

method.

    Label(Unit *unit, const_Onceref rtype, const string &name);

The arguments are similar to the Perl version, only the Unit is passed as an argument to the Label constructor.

The constructed label keeps a reference to its row type, and a pointer (not reference, to avoid the circular references!) to the unit. The unit automatically keeps a reference to the label, so there is no need to call

    Unit::rememberLabel()

manually. On the other hand, if you do not want the label to be remembered by its unit (though why?), the only way to achieve that is to call

    Unit::forgetLabel()

after its construction.

Now, the public methods of Label.

    const string &getName() const;
    const RowType *getType() const;
    Unit *getUnitPtr() const;

Read back the information from the constructor. The method

    getUnitPtr()

is named this way and not

    getUnit()

to emphasize that the Label has only a pointer to the Unit, not a reference. After the label gets cleared,

    getUnitPtr()

will return NULL.The reason is that after that the label doesn't know any more whether the unit still exists or has been deleted, and doesn't want to return a pointer to a potentially freed memory.

    const string &getUnitName() const;

A convenience method for the special case of getting the label's unit name. It's used in many error message. You can't just say

    label->getUnitPtr()->getName()

because

    getUnitPtr()

might return a NULL if the label has been already cleared.

    getUnitName()

takes care of it and returns a special string "[label cleared]" if the label has been cleared.

    void clear();

Clears the label. After that the label stops working. Note that clearing a label doesn't disconnect it from its unit. Well, the label won't tell you its unit any more (the pointer will be reset to NULL) but the unit will still have a reference to the label! Use the unit's method

    forgetLabel()

to disconnect it (but that won't clear the label itself, so you have to call both

    unit->forgetLabel()

and

    label->clear()

). Of course, if you call

    unit->clearLabels()

, that would take care of everything.

Clearing cleans the chaining list of this label but doesn't call recursively

    clear()

on the formerly chained labels. If you need that, you have to do it yourself.

    bool isCleared() const;

Check if the label has been cleared.

    void setNonReentrant();
    bool isNonReentrant() const;

Mark the label as non-reentrant, and check this flag. There is no way to unset this flag. The meaning of it is described in &xrsp;.

    Erref chain(Onceref lab, bool front = false);

Chain another label to this one (so when this label is executed, the chained labels will also be executed in order). This label will keep a reference of the chained label. The circular chainings are forbidden and will throw an Exception. If the argument

    front

is

    false

(default), the chaining will be done at the back of the chain, if

    true

then at the front, same as the method

    chainFront()

in the Perl API. In the &Cpp; API both kinds of chainings are done with the same method.

    typedef vector > ChainedVec;
    const ChainedVec &getChain() const;

Get back the information about the chained labels. This returns a reference to the internal vector, so if the chainings are changed afterwards, the changes will be visible in the vector.

    bool hasChained() const;

A quick check, whether there is anything chained.

    void clearChained();

Clear the chaining list of this label. (But doesn't call

    clear()

on these labels!)

    Rowop *adopt(Rowop *from) const;

A convenient factory method for adopting the rowops. Treat it similarly to a constructor: the returned Rowop will be newly constructed and have the reference count of 0; the returned pointer must be stored in an Autoref (or Onceref). This method by itself doesn't check whether the original Rowop has a matching type, it simply makes a copy with the label reference replaced. It's up to you to make sure that the labels are correct.

A special subclass of the Label is DummyLabel: it's a label that does nothing. It's

    execute()

method is empty. It's constructed very similarly to the normal Label:

    DummyLabel(Unit *unit, const_Onceref rtype, const string &name);

The dummy labels are convenient for chaining the other labels to them.

label
DummyLabel