Classes | Functions

GenericFieldHandles

Generic field handle classes, used to reference and work with record members in a flexible, indirect way. More...

Classes

struct  Barry::FieldIdentity
 This class holds data that identifies a given field in a record. More...
class  Barry::EnumConstants
 This is the base class for the hierarchy of classes to define enum record members. More...
class  Barry::FieldValueHandlerBase
 This is a pure virtual base class, defining the various types that record fields can be. More...
class  Barry::EnumFieldBase< RecordT >
 EnumFieldBase<RecordT> More...
class  Barry::EnumField< RecordT, EnumT >
 EnumField<RecordT, EnumT> More...
class  Barry::FieldHandle< RecordT >
 This is a template class that handles pointers to members of multiple types of data and multiple types of records. More...
class  Barry::FieldSorter< RecordT >
 FieldSorter<> is a helper class for NamedFieldCmp<>, used as the callback for FieldHandle<>::Member(). More...
class  Barry::NamedFieldCmp< RecordT >
 A comparison functor, intended to be used in std::sort(), which allows sorting by a particular record's member variable, selected by string name. More...
class  Barry::DBNamedFieldCmp
 This class is a wrapper around the NamedFieldCmp<>, allowing you to sort a vector (or other container) of DBData objects. More...

Functions

template<class RecordT , class TypeT >
FieldHandle< RecordT > Barry::MakeFieldHandle (TypeT RecordT::*tp, const FieldIdentity &id)
 Factory function to create a FieldHandle<> object.
template<class HandlesT , class CallbackT >
void Barry::ForEachField (const HandlesT &handles, const CallbackT &func)
 Calls FieldHandle<>::Member() for each defined field for a given record type.
template<class RecordT >
void Barry::ForEachFieldValue (const RecordT &rec, const FieldValueHandlerBase &vh)
 Calls FieldHandle<>::Value() for each defined field for a given record.

Detailed Description

Generic field handle classes, used to reference and work with record members in a flexible, indirect way.

There are two ways to access device record data. The obvious way is to instantiate a record class, such as Contact, and access the public data members of that class to read and write. If you always work with the same record class, this works fine.

The other way is to have a list of pointers to members. For example, you may wish to compare two records, without actually caring what data is in each one. You can compare at the record class level, with Contact one, two; and then if( one == two ), but this will not tell you what field in the record changed.

This last feature is what Generic Field Handles are meant to fix. Each record class will contain a GetFieldHandles() member function, which will return a list of type FieldHandle<T>::ListT (currently a std::vector<>) objects, for that specific record. For example, Contact would fill the ListT with FieldHandle<Contact> objects. Each FieldHandle<> object contains a C++ pointer-to-member, which the FieldHandle refers to, as well as a FieldIdentity object. The FieldIdentity object contains various identitying information, such as the C++ variable name, an English (or localized language) display name of the field, suitable for user prompts, and other data more useful to the library.

The FieldHandle<> object has two member functions: Value() and Member().

Value() will call a callback function with the _value_ of the variable that FieldHandle<> points to. For example, if the FieldHandle<> points to a std::string record member variable, then Value() will pass that string value in as an argument, along with a reference to the FieldIdentity object. Value() requires a callback object and a record object to perform this callback.

Member() will call a callback function/functor with the pointer-to-member pointer and the FieldIdentity object. This allows the programmer to create a functor with multiple record objects, perhaps two objects to compare individual fields, and use the pointer-to-member to access the field data as needed.

For now, all data and callbacks are const, meaning that it is not possible (without const_casting) to write to the record via the pointers-to-members. This design decision may need to be revisited someday, depending on its usefulness.


Function Documentation

template<class HandlesT , class CallbackT >
void Barry::ForEachField ( const HandlesT &  handles,
const CallbackT &  func 
)

Calls FieldHandle<>::Member() for each defined field for a given record type.

Takes a FieldHandle<>::ListT containing FieldHandle<> objects, and calls Member(func) for each one.

Definition at line 1197 of file record.h.

template<class RecordT >
void Barry::ForEachFieldValue ( const RecordT &  rec,
const FieldValueHandlerBase &  vh 
)

Calls FieldHandle<>::Value() for each defined field for a given record.

Takes a RecordT object and calls Value(vh, rec) for each FieldHandle<> object in the record's FieldHandles set.

Definition at line 1211 of file record.h.

References Barry::FieldHandle< RecordT >::Value().

Here is the call graph for this function:

template<class RecordT , class TypeT >
FieldHandle<RecordT> Barry::MakeFieldHandle ( TypeT RecordT::*  tp,
const FieldIdentity &  id 
)

Factory function to create a FieldHandle<> object.

Definition at line 1187 of file record.h.