aboutsummaryrefslogtreecommitdiff
path: root/src/variable.h
blob: 3d3664849be18e2f8c45f0bd3edb8d2b633c1744 (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
129
130
131
132
133
134
135
/*
 * Copyright (C) 2007-2014 Xagasoft, All rights reserved.
 *
 * This file is part of the Xagasoft Build and is released under the
 * terms of the license contained in the file LICENSE.
 */

#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