FBB::CmdFinder(3bobcat)

Command-function associations
(libbobcat-dev_4.08.03-x.tar.gz)

2005-2018

NAME

FBB::CmdFinder - Determine (member) function associated with a command

SYNOPSIS

#include <bobcat/cmdfinder>
Linking option: -lbobcat

DESCRIPTION

Objects of the class CmdFinder determine which (member) function to call given a command. Although associations between commands and (member) functions are often defined in a switch, a switch is not the preferred way to define these associations because of the fect that the maintainability and clarity of switches suffer for even moderately large command sets. Moreover, the switch is hardly ever self-supporting, since usually some command-processing is required to determine command/case-value associations.

The alternative (and preferred) approach, which is also taken by CmdFinder is to define an array of pointers to (member) functions, and to define the associations between commands and member functions as a mapping of commands to array indices. Plain associations between (textual) commands and functions to be called can also easily be defined using a std::map or other hash-type data structure. However, the syntactical requirements for such a std::map structure are non-trivial, and besides: user-entered commands often require some preprocessing before a command can be used as an index in a std::map.

The class CmdFinder is an attempt to offer a versatile implementation of associations between commands and (member) functions. In particular, the class offers the following features:

The class CmdFinder itself is defined as a template class. This template class should be used as a base class of a user-defined derived class defining the array of command-function associations. The class CmdFinder itself is a derived class of the class CmdFinderBase, defining some template-independent functionality that is used by CmdFinder. The enumeration and member functions sections below also contain the members that are available to classes derived from CmdFinder, but which are actually defined in the class CmdFinderBase.

NAMESPACE

FBB
All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace FBB.

INHERITS FROM

FBB::CmdFinderBase

ENUMERATION

The enumeration Mode is defined in the class CmdFinderBase. It contains the following values, which may be combined by the bit_or operator to specify the CmdFinder object's required mode of operation: So, by default a full, literal match between provided command and predefined command-keys is required.

TEMPLATE TYPE PARAMETER

The template class CmdFinder has one template type parameter, which is the prototype of the functions defined in the array of command-function associations. This type becomes available as the typename FunctionPtr (defined by the class CmdFinder in the class that is derived from CmdFinder).

PROTECTED DEFINED TYPES

The following (protected) types are defined by the template class CmdFinder:

CONSTRUCTORS

Copy and move constructors are available.

OVERLOADED OPERATORS

The copy and move assignment operators are available.

PUBLIC MEMBER FUNCTION

PROTECTED MEMBER FUNCTIONS

PROTECTED DATA MEMBERS

The class CmdFinder has access to some protected data members of the class CmdFinderBase, which should not be used or modified by classes derived from CmdFinder.

EXAMPLE

#include <iostream>
#include <string>

#include <bobcat/cmdfinder>

using namespace std;
using namespace FBB;

// Define a class `Command' in which the array s_action defines the
// command-function associations. Command is derived from CmdFinder,
// specifying the prototype of the member functions to be called

class Command: public CmdFinder<bool (Command::*)() const> 
{
    static Entry s_action[];

    bool add() const                       // some member functions
    {
        cout << "add called: command was `" << cmd() << "'\n";
        if (beyond().length())
            cout << "Beyond " << cmd() << " `" << beyond() << "'\n"; 
        return true;
    }
    bool error() const
    {
        cout << "unrecognized command: `" << cmd() << "' called\n" <<
                count() << " matching alternatives found\n";
        return true;
    }
    bool quit() const
    {
        cout << "quit called: quitting this series\n";
        return false;
    }

    public:
        Command();                      // Declare the default constructor

        bool run(std::string const &cmd)    // run a command
        {
            return (this->*findCmd(cmd))(); // execute the command matching
                                            // 'cmd' 
        }
};

// Define command-function associations. Note that the last is given an empty
// command-text. This is not required, a command text could have been
// specified for the last command as well.

Command::Entry Command::s_action[] =
{
    Entry("add",    &Command::add),
    Entry("quit",   &Command::quit),
    Entry("",       &Command::error),
};

// Define the default constructor
Command::Command()                       // Define the default constructor
:                               // Note the use of `FunctionPtr'
    CmdFinder<FunctionPtr>(s_action, s_action + 
                                    sizeof(s_action) / sizeof(Entry))
{}

void run(Command &cmd, char const *descr, size_t mode = 0)
{
    if (mode)
        cmd.setMode(mode);

    cout << "Enter 5 x a command using " << descr << ".\n";
    for (size_t idx = 0; idx++ < 5; )
    {
        cout << "Enter command " << idx << ": ";
        string text;
        getline(cin, text);
        if (!cmd.run(text))     // run a command
            break;
    }
}

int main()
{
    Command cmd;                // define a command

                                // enter 5 commands using the default mode
    run (cmd, "the default mode");
    run (cmd, "abbreviated commands", Command::UNIQUE);
    run (cmd, "abbreviated case-insensitive commands", 
                                   Command::UNIQUE | Command::INSENSITIVE);
    run (cmd, "abbreviated command lines", 
                                   Command::USE_FIRST | Command::UNIQUE);
    run (cmd, "abbreviated case-insensitive command lines", 
                                   Command::USE_FIRST | Command::UNIQUE |
                                                        Command::INSENSITIVE);
    return 0;
}








FILES

bobcat/cmdfinder - defines the class interface
bobcat/cmdfinderbase - defines the base class of CmdFinder.

SEE ALSO

bobcat(7), cmdfinderbase(3bobcat), exception(3bobcat)

BUGS

None Reported.

DISTRIBUTION FILES

BOBCAT

Bobcat is an acronym of `Brokken's Own Base Classes And Templates'.

COPYRIGHT

This is free software, distributed under the terms of the GNU General Public License (GPL).

AUTHOR

Frank B. Brokken (f.b.brokken@rug.nl).