source: branches/vendor/trolltech/qt/current/tools/qtconcurrent/codegenerator/src/codegenerator.h @ 2

Last change on this file since 2 was 2, checked in by Dmitry A. Kuminov, 13 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 7.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file.  Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file.  Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41#ifndef CODEGENERATOR_H
42#define CODEGENERATOR_H
43
44#include <QByteArray>
45#include <QString>
46#include <QList>
47#include <QStack>
48
49namespace CodeGenerator
50{
51    enum GeneratorType {NoopType, CompoundType, TextType, RepeaterType, CounterType, GroupType};
52    class BaseGenerator;
53    typedef QStack<BaseGenerator *> GeneratorStack;
54   
55    template <typename ValueType>
56    class Stacker {
57    public:
58        Stacker(QStack<ValueType> *stack, ValueType value) : stack(stack) { stack->push(value); }
59        ~Stacker() { stack->pop();}
60    private:
61        QStack<ValueType> *stack;
62    };
63    typedef Stacker<BaseGenerator *> GeneratorStacker;
64   
65    class BaseGenerator
66    {
67    public:
68        BaseGenerator(GeneratorType type = NoopType) : type(type) {}
69        virtual ~BaseGenerator() {};
70        virtual QByteArray generate(GeneratorStack *stack) { Q_UNUSED(stack); return QByteArray(); };
71        int currentCount(GeneratorStack *stack) const;
72        int repeatCount(GeneratorStack *stack) const;
73        GeneratorType type;   
74    };
75
76    class Item
77    {
78    public:
79        Item(BaseGenerator * const base) : generator(base) {}
80        Item(const char * const text);
81        QByteArray generate() const
82        {  GeneratorStack stack; return generator->generate(&stack);  }
83        // ### TODO: Fix memory leak!
84        // QExplicitlySharedDataPointer<BaseGenerator> generator;
85        BaseGenerator * const generator;
86    };
87   
88    class CompoundGenerator : public BaseGenerator
89    {
90    public:
91        CompoundGenerator(BaseGenerator * const a, BaseGenerator * const b) 
92          : BaseGenerator(CompoundType), a(a), b(b) {}
93        virtual QByteArray generate(GeneratorStack *stack)
94        { return a->generate(stack) + b->generate(stack); };
95    protected:   
96        BaseGenerator * const a;
97        BaseGenerator * const b;
98    };
99   
100    class Compound : public Item
101    {
102    public:
103        Compound(const Item &a, const Item &b) : Item(new CompoundGenerator(a.generator, b.generator)) {}
104    };
105   
106    class TextGenerator : public BaseGenerator
107    {
108    public:
109        TextGenerator(const QByteArray &text) : BaseGenerator(TextType), text(text) {}
110        virtual QByteArray generate(GeneratorStack *) { return text; };
111    protected:   
112        QByteArray text;
113    };
114       
115    class Text : public Item {
116    public:
117        Text(const QByteArray &text) : Item(new TextGenerator(text)) {}
118        Text(const char * const text) : Item(new TextGenerator(QByteArray(text))) {}
119    };
120
121    class RepeaterGenerator : public BaseGenerator
122    {
123    public:
124        RepeaterGenerator(BaseGenerator * const childGenerator) 
125          : BaseGenerator(RepeaterType), repeatCount(1), repeatOffset(0), childGenerator(childGenerator) {}
126        virtual QByteArray generate(GeneratorStack *stack);
127
128        int repeatCount;
129        int repeatOffset;
130        int currentRepeat;
131        BaseGenerator * const childGenerator;
132    };
133   
134    class Repeater : public Item {
135    public:
136        Repeater(const Item &item) : Item(new RepeaterGenerator(item.generator)) {}
137        void setRepeatCount(int count) 
138        { static_cast<RepeaterGenerator * const>(generator)->repeatCount = count;  }
139        void setRepeatOffset(int offset)
140        { static_cast<RepeaterGenerator * const>(generator)->repeatOffset = offset;  }
141    };
142   
143    class CounterGenerator : public BaseGenerator
144    {
145    public:
146        CounterGenerator() : BaseGenerator(CounterType), offset(0), increment(1), reverse(false) {}
147        QByteArray generate(GeneratorStack *stack)
148        { 
149            if (reverse)
150                return QByteArray::number(repeatCount(stack) - (currentCount(stack) * increment) + offset + 1);
151            else
152                return QByteArray::number((currentCount(stack) * increment) + offset);
153        }
154        int offset;
155        int increment;
156        bool reverse;
157    };
158   
159    class Counter : public Item {
160    public:
161        Counter() : Item(new CounterGenerator()) {}
162        Counter(int offset) : Item(new CounterGenerator()) { setOffset(offset); }
163        void setOffset(int offset)
164        { static_cast<CounterGenerator *>(generator)->offset = offset; }
165        void setIncrement(int increment)
166        { static_cast<CounterGenerator *>(generator)->increment = increment; }
167        void setReverse(bool reverse)
168        { static_cast<CounterGenerator *>(generator)->reverse = reverse; }
169
170    };
171   
172    class GroupGenerator : public BaseGenerator
173    {
174    public:
175        GroupGenerator(BaseGenerator * const childGenerator)
176          : BaseGenerator(GroupType), currentRepeat(0), childGenerator(childGenerator), 
177            separator(new BaseGenerator()), prefix(new BaseGenerator()), postfix(new BaseGenerator()) { }
178        virtual QByteArray generate(GeneratorStack *stack);
179        int currentRepeat;
180        BaseGenerator * const childGenerator;
181        BaseGenerator *separator;
182        BaseGenerator *prefix;
183        BaseGenerator *postfix;
184    };
185   
186    class Group : public Item
187    {
188    public:
189        Group(const Item &item) : Item(new GroupGenerator(item.generator)) { setSeparator(", "); }
190        void setSeparator(const Item &separator)       
191        { static_cast<GroupGenerator *>(generator)->separator = separator.generator; }
192        void setPrefix(const Item &prefix)       
193        { static_cast<GroupGenerator *>(generator)->prefix = prefix.generator; }
194        void setPostfix(const Item &postfix)       
195        { static_cast<GroupGenerator *>(generator)->postfix = postfix.generator; }
196    };
197
198    const Compound operator+(const Item &a, const Item &b); 
199    const Compound operator+(const Item &a, const char * const text);
200    const Compound operator+(const char * const text, const Item &b);
201
202} //namespace CodeGenerator
203
204#endif
Note: See TracBrowser for help on using the repository browser.