aboutsummaryrefslogtreecommitdiff
path: root/src/variable.h
blob: f6c2044d62b6f1e4aea0fecb4d79c0d4c98317e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef VARIABLE_H
#define VARIABLE_H

#include "types.h"
#include <bu/archivebase.h>

/**
 * A build variable, which is basically a flexible, limited type range variant.
 */
class Variable
{
friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Variable &v );
friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Variable &v );
public:
    enum Type
    {
        typeNone,
        typeBool,
        typeInt,
        typeFloat,
        typeVersion,
        typeString,
        typeList,
        typeRef,            /**< Reference by name, it's just a string. */
        typeOpaque          /**< Only useful to functions. */
    };

public:
    Variable();
    Variable( Type t );
    Variable( int iVal );
    Variable( double fVal );
    Variable( bool bVal );
    Variable( const Bu::String &sVal );
    Variable( const char *sVal );
    Variable( const Variable &v );
    Variable( const class AstLeaf &l );
    /**
     * This special case function turns the variable into a string if there is
     * only one string in the list, or a list of strings if there is more or
     * less than one.
     */
    Variable( const StrList &lst );
    Variable( const VarList &lst );
    Variable( void *oVal );
    virtual ~Variable();

    static Variable mkRef( const Bu::String &sVal );

    Type getType() const;

    // Raw aquisition functions, if the type isn't right,
    // they throw an exception
    int getInt() const;
    double getFloat() const;
    bool getBool() const;
    const Bu::String &getString() const;
    const VarList &getList() const;
    const void *getOpaque() const;

    // Conversion functions, they'll return the requested type, maybe an error
    // if the source data is really bad
    int toInt() const;
    double toFloat() const;
    bool toBool() const;
    Bu::String toString() const;
    VarList toList() const;

    Variable toType( Type eNewType ) const;

    void append( const Variable &v );
    VarList::iterator begin();
    VarList::const_iterator begin() const;

    void doNegate();
    void doNot();

    const Variable &operator=( const Variable &rhs );
    const Variable &operator=( const int &rhs );
    const Variable &operator=( const double &rhs );
    const Variable &operator=( const bool &rhs );
    const Variable &operator=( const Bu::String &rhs );
    const Variable &operator=( void *rhs );

    const Variable &operator+=( const Variable &rhs );
    const Variable &operator<<( const Variable &rhs );

    bool operator==( const Variable &rhs ) const;
    bool operator!=( const Variable &rhs ) const;
    bool operator<( const Variable &rhs ) const;
    bool operator>( const Variable &rhs ) const;
    bool operator<=( const Variable &rhs ) const;
    bool operator>=( const Variable &rhs ) const;

    Variable operator+( const Variable &rhs ) const;
    Variable operator-( const Variable &rhs ) const;
    Variable operator*( const Variable &rhs ) const;
    Variable operator/( const Variable &rhs ) const;

private:
    Type eType;
    union
    {
        int iVal;
        double fVal;
        bool bVal;
        Bu::String *sVal;
        VarList *lVal;
        void *oVal;
    } uVal;

    void reset( Type eType );
};

namespace Bu
{
    class Formatter;
}

Bu::Formatter &operator<<( Bu::Formatter &f, const Variable::Type &t );
Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v );

Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Variable &v );
Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Variable &v );

VarList operator-( const VarList &rBase, const VarList &rSub );

#endif