Класс ValueSet

Класс ValueSet представляет собой контейнер для некоторых типов данных и может использоваться в этом качестве, хотя основное его назначение - быть универсальным параметром для функций. Такой параметр удобен в нескольких случаях. Например, если у функции много входных параметров и в процессе развития программы они часто меняются. Или когда используются указатели на функции, но сами функции могут иметь разные параметры.

class ValueSet
{
public:
    enum Type
    {
        out_of_range, 
        void_type, void_ptr_type, cvoid_ptr_type,
        bool_type, bool_ptr_type, cbool_ptr_type,
        char_type, char_ptr_type, cchar_ptr_type,
        int_type, int_ptr_type, cint_ptr_type,
        nat_type, nat_ptr_type, cnat_ptr_type,
        dbl_type, dbl_ptr_type, cdbl_ptr_type,
    };
private:
    union Value
    {
              void   * vp;
        const void   * cvp;
              bool     b;
              bool   * bp;
        const bool   * cbp;
              char     c;
              char   * cp;
        const char   * ccp;
              int      i;
              int    * ip;
        const int    * cip;
              nat      n;
              nat    * np;
        const nat    * cnp;
              double   d;
              double * dp;
        const double * cdp;
    };
    class Node
    {
    public:
        Value value;
        Type  type;
    };
// Data
    Node * data;
    nat nn, max_size;
// Functions
    void resize ( nat index );
    ValueSet ( const ValueSet & );
public:
    ValueSet ( nat ms = 1024 );
    ValueSet & operator = ( const ValueSet & );
    ValueSet & swap ( ValueSet & vs )
    {
        _swap ( max_size, vs.max_size );
        _swap ( data, vs.data );
        _swap ( nn, vs.nn );
        return *this;
    }
   ~ValueSet () { delete[] data; }

    nat size () const { return max_size; }
    Type type ( nat index ) const;
    void clear ();

    bool putVoid    ( nat index );
    bool putVoidPtr ( nat index, void * value );
    bool putCVoidPtr( nat index, const void * value );

    bool putBool    ( nat index, bool value );
    bool putBoolPtr ( nat index, bool * value );
    bool putCBoolPtr( nat index, const bool * value );

    bool putChar    ( nat index, char value );
    bool putCharPtr ( nat index, char * value );
    bool putCCharPtr( nat index, const char * value );

    bool putInt    ( nat index, int value );
    bool putIntPtr ( nat index, int * value );
    bool putCIntPtr( nat index, const int * value );

    bool putNat    ( nat index, nat value );
    bool putNatPtr ( nat index, nat * value );
    bool putCNatPtr( nat index, const nat * value );

    bool putDbl    ( nat index, double value );
    bool putDblPtr ( nat index, double * value );
    bool putCDblPtr( nat index, const double * value );
    
    bool getVoidPtr ( nat index, void * & value ) const;
    bool getCVoidPtr( nat index, const void * & value ) const;

    bool getBool    ( nat index, bool & value ) const;
    bool getBoolPtr ( nat index, bool * & value ) const;
    bool getCBoolPtr( nat index, const bool * & value ) const;

    bool getChar    ( nat index, char & value ) const;
    bool getCharPtr ( nat index, char * & value ) const;
    bool getCCharPtr( nat index, const char * & value ) const;

    bool getInt    ( nat index, int & value ) const;
    bool getIntPtr ( nat index, int * & value ) const;
    bool getCIntPtr( nat index, const int * & value ) const;

    bool getNat    ( nat index, nat & value ) const;
    bool getNatPtr ( nat index, nat * & value ) const;
    bool getCNatPtr( nat index, const nat * & value ) const;

    bool getDbl    ( nat index, double & value ) const;
    bool getDblPtr ( nat index, double * & value ) const;
    bool getCDblPtr( nat index, const double * & value ) const;
};

Данный класс реализован как массив, максимальный размер которого можно указать в конструкторе ( по умолчанию он равен 1024 ). Реальный размер массива обычно меньше и он меняется по мере загрузки данных. Доступ к данным осуществляется по индексу, при этом учитывается тип данных, и, если в массиве под индексом i лежит число типа int, а будет попытка прочитать его функцией getDbl, то чтения не будет, а функция вернёт значение false. Единственное исключение - если в ячейке лежит указатель на неконстантный объект, то его можно прочитать также и функцией для константного объекта. При желании можно узнать максмальный размер контейнера ( функция size() ) и тип объекта в ячейке ( функция type(int) ). Во втором случае, если индекс выйдет за пределы контейнера, то функция type вернёт значение out_of_range, а если индекс нормальный, но ячейка ещё не была заполнена, то void_type. Для того, чтобы работать с другими типами данных можно использовать указатели типа void * или const void *. В качестве индексов удобно использовать перечисления ( enum ). Тогда параметры получат имена, как обычные параметры функций. Методы clear() и putVoid(int) предназначены для того, чтобы "стирать" данные.

Исходники находятся в source.zip.

Наверх