File: nanglestructurelist.h

package info (click to toggle)
regina-normal 4.5-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 16,824 kB
  • ctags: 7,862
  • sloc: cpp: 63,296; ansic: 12,913; sh: 10,556; perl: 3,294; makefile: 947; python: 188
file content (431 lines) | stat: -rw-r--r-- 16,232 bytes parent folder | download
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

/**************************************************************************
 *                                                                        *
 *  Regina - A Normal Surface Theory Calculator                           *
 *  Computational Engine                                                  *
 *                                                                        *
 *  Copyright (c) 1999-2008, Ben Burton                                   *
 *  For further details contact Ben Burton (bab@debian.org).              *
 *                                                                        *
 *  This program is free software; you can redistribute it and/or         *
 *  modify it under the terms of the GNU General Public License as        *
 *  published by the Free Software Foundation; either version 2 of the    *
 *  License, or (at your option) any later version.                       *
 *                                                                        *
 *  This program is distributed in the hope that it will be useful, but   *
 *  WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *  General Public License for more details.                              *
 *                                                                        *
 *  You should have received a copy of the GNU General Public             *
 *  License along with this program; if not, write to the Free            *
 *  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,       *
 *  MA 02110-1301, USA.                                                   *
 *                                                                        *
 **************************************************************************/

/* end stub */

/*! \file nanglestructurelist.h
 *  \brief Contains a packet representing a collection of angle
 *  structures on a triangulation.
 */

#ifndef __NANGLESTRUCTURELIST_H
#ifndef __DOXYGEN
#define __NANGLESTRUCTURELIST_H
#endif

#include <algorithm>
#include <iterator>
#include <vector>
#include "angle/nanglestructure.h"
#include "packet/npacket.h"
#include "utilities/memutils.h"
#include "utilities/nproperty.h"
#include "utilities/nthread.h"

namespace regina {

class NProgressManager;
class NXMLPacketReader;
class NXMLAngleStructureListReader;

/**
 * \weakgroup angle
 * @{
 */

/**
 * A packet representing a collection of angle structures on a triangulation.
 * Such a packet must always be a child packet of the triangulation on
 * which the angle structures lie.  If this triangulation changes, the
 * information contained in this packet will become invalid.
 *
 * Angle structure lists should be created using the routine enumerate(),
 * which is new as of Regina 3.95.
 *
 * \testpart
 */
class NAngleStructureList : public NPacket, public NFilePropertyReader {
    public:
        static const int packetType;

    private:
        std::vector<NAngleStructure*> structures;
            /**< Contains the angle structures stored in this packet. */

        mutable NProperty<bool> doesAllowStrict;
            /**< Does the convex span of this list include a strict
             *   angle structure? */
        mutable NProperty<bool> doesAllowTaut;
            /**< Does the convex span of this list include a taut structure? */

    public:
        /**
         * Destroys this list and all the angle structures within.
         */
        virtual ~NAngleStructureList();

        /**
         * Returns the triangulation on which these angle structures
         * lie.
         *
         * @return the corresponding triangulation.
         */
        NTriangulation* getTriangulation() const;

        /**
         * Returns the number of angle structures stored in this list.
         *
         * @return the number of angle structures.
         */
        unsigned long getNumberOfStructures() const;
        /**
         * Returns the angle structure at the requested index in this
         * list.
         *
         * @param index the index of the requested angle structure in
         * this list; this must be between 0 and
         * getNumberOfStructures()-1 inclusive.
         * @return the angle structure at the requested index.
         */
        const NAngleStructure* getStructure(unsigned long index) const;

        /**
         * Determines whether any convex combination of the angle
         * structures in this list is a strict angle structure.
         * See NAngleStructure::isStrict() for details on strict angle
         * structures.
         *
         * @return \c true if and only if a strict angle structure can
         * be produced.
         */
        bool allowsStrict() const;
        /**
         * Determines whether any convex combination of the angle
         * structures in this list is a taut structure.
         * See NAngleStructure::isTaut() for details on taut
         * structures.
         *
         * @return \c true if and only if a taut structure can be produced.
         */
        bool allowsTaut() const;

        /**
         * Enumerates all angle structures on the given triangulation.
         * A list containing all vertices of the angle structure solution
         * space will be returned.
         *
         * The angle structure list that is created will be inserted as the
         * last child of the given triangulation.  This triangulation \b must
         * remain the parent of this angle structure list, and must not
         * change while this angle structure list remains in existence.
         *
         * If a progress manager is passed, the angle structure
         * enumeration will take place in a new thread and this routine
         * will return immediately.  The NProgress object assigned to
         * this progress manager is guaranteed to be of the class
         * NProgressNumber.
         *
         * If no progress manager is passed, the enumeration will run
         * in the current thread and this routine will return only when
         * the enumeration is complete.  Note that this enumeration can
         * be extremely slow for larger triangulations.
         *
         * @param owner the triangulation for which the vertex
         * angle structures will be enumerated.
         * @param manager a progress manager through which progress will
         * be reported, or 0 if no progress reporting is required.  If
         * non-zero, \a manager must point to a progress manager for
         * which NProgressManager::isStarted() is still \c false.
         * @return the newly created angle structure list.  Note that if
         * a progress manager is passed then this list may not be completely
         * filled when this routine returns.  If a progress manager is
         * passed and a new thread could not be started, this routine
         * returns 0 (and no angle structure list is created).
         */
        static NAngleStructureList* enumerate(NTriangulation* owner,
            NProgressManager* manager = 0);

        virtual int getPacketType() const;
        virtual std::string getPacketTypeName() const;
        virtual void writeTextShort(std::ostream& out) const;
        virtual void writeTextLong(std::ostream& out) const;
        static NXMLPacketReader* getXMLReader(NPacket* parent);
        virtual void writePacket(NFile& out) const;
        static NAngleStructureList* readPacket(NFile& in, NPacket* parent);
        virtual bool dependsOnParent() const;

    protected:
        /**
         * Creates a new angle structure list performing no
         * initialisation whatsoever other than property initialisation.
         */
        NAngleStructureList();

        virtual NPacket* internalClonePacket(NPacket* parent) const;
        virtual void writeXMLPacketData(std::ostream& out) const;
        virtual void readIndividualProperty(NFile& infile, unsigned propType);

        /**
         * Calculate whether the convex span of this list includes a
         * strict angle structure.
         */
        void calculateAllowStrict() const;
        /**
         * Calculate whether the convex span of this list includes a
         * taut structure.
         */
        void calculateAllowTaut() const;

        /**
         * An output iterator used to insert angle structures into an
         * NAngleStructureList.
         *
         * Objects of type <tt>NAngleStructure*</tt> and
         * <tt>NAngleStructureVector*</tt> can be assigned to this
         * iterator.  In the latter case, a surrounding NAngleStructure
         * will be automatically created.
         */
        struct StructureInserter : public std::iterator<
                std::output_iterator_tag, void, void, void, void> {
            NAngleStructureList* list;
                /**< The list into which angle structures will be inserted. */
            NTriangulation* owner;
                /**< The triangulation on which the angle structures to
                 *   be inserted lie. */

            /**
             * Creates a new uninitialised output iterator.
             *
             * \warning This iterator must not be used until its
             * structure list and triangulation have been initialised.
             */
            StructureInserter();
            /**
             * Creates a new output iterator.  The member variables of
             * this iterator will be initialised according to the
             * parameters passed to this constructor.
             *
             * @param newList the list into which angle structures will
             * be inserted.
             * @param newOwner the triangulation on which the structures
             * to be inserted lie.
             */
            StructureInserter(NAngleStructureList& newList,
                NTriangulation* newOwner);
            /**
             * Creates a new output iterator that is a clone of the
             * given iterator.
             *
             * @param cloneMe the output iterator to clone.
             */
            StructureInserter(const StructureInserter& cloneMe);

            /**
             * Sets this iterator to be a clone of the given output iterator.
             *
             * @param cloneMe the output iterator to clone.
             * @return this output iterator.
             */
            StructureInserter& operator =(const StructureInserter& cloneMe);

            /**
             * Appends an angle structure to the end of the appropriate
             * structure list.
             *
             * The given angle structure will be deallocated with the
             * other angle structures in this list.
             *
             * @param structure the angle structure to insert.
             * @return this output iterator.
             */
            StructureInserter& operator =(NAngleStructure* structure);
            /**
             * Appends the angle structure corresponding to the given
             * vector to the end of the appropriate structure list.
             *
             * The given vector will be owned by the newly created
             * angle structure and will be deallocated with the
             * other angle structures in this list.
             *
             * @param vector the vector of the angle structure to insert.
             * @return this output iterator.
             */
            StructureInserter& operator =(NAngleStructureVector* vector);

            /**
             * Returns a reference to this output iterator.
             *
             * @return this output iterator.
             */
            StructureInserter& operator *();
            /**
             * Returns a reference to this output iterator.
             *
             * @return this output iterator.
             */
            StructureInserter& operator ++();
            /**
             * Returns a reference to this output iterator.
             *
             * @return this output iterator.
             */
            StructureInserter& operator ++(int);
        };

    private:
        /**
         * A thread class that actually performs the angle structure
         * enumeration.
         */
        class Enumerator : public NThread {
            private:
                NAngleStructureList* list;
                    /**< The angle structure list to be filled. */
                NTriangulation* triang;
                    /**< The triangulation upon which this angle
                         structure list will be based. */
                NProgressManager* manager;
                    /**< The progress manager through which progress is
                         reported, or 0 if no progress manager is in use. */

            public:
                /**
                 * Creates a new enumerator thread with the given
                 * parameters.
                 *
                 * @param newList the angle structure list to be filled.
                 * @param useTriang the triangulation upon which this
                 * angle structure list will be based.
                 * @param useManager the progress manager to use for
                 * progress reporting, or 0 if progress reporting is not
                 * required.
                 */
                Enumerator(NAngleStructureList* newList,
                    NTriangulation* useTriang, NProgressManager* useManager);

                void* run(void*);
        };

    friend class regina::NXMLAngleStructureListReader;
};

/*@}*/

// Inline functions for NAngleStructureList

inline NAngleStructureList::~NAngleStructureList() {
    for_each(structures.begin(), structures.end(),
        FuncDelete<NAngleStructure>());
}

inline unsigned long NAngleStructureList::getNumberOfStructures() const {
    return structures.size();
}

inline const NAngleStructure* NAngleStructureList::getStructure(
        unsigned long index) const {
    return structures[index];
}

inline bool NAngleStructureList::allowsStrict() const {
    if (! doesAllowStrict.known())
        calculateAllowStrict();
    return doesAllowStrict.value();
}

inline bool NAngleStructureList::allowsTaut() const {
    if (! doesAllowTaut.known())
        calculateAllowTaut();
    return doesAllowTaut.value();
}

inline bool NAngleStructureList::dependsOnParent() const {
    return true;
}

inline NAngleStructureList::NAngleStructureList() {
}

inline NAngleStructureList::StructureInserter::StructureInserter() : list(0),
        owner(0) {
}

inline NAngleStructureList::StructureInserter::StructureInserter(
        NAngleStructureList& newList, NTriangulation* newOwner) :
        list(&newList), owner(newOwner) {
}

inline NAngleStructureList::StructureInserter::StructureInserter(
        const StructureInserter& cloneMe) : list(cloneMe.list),
        owner(cloneMe.owner) {
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator =(
        const StructureInserter& cloneMe) {
    list = cloneMe.list;
    owner = cloneMe.owner;
    return *this;
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator =(
        NAngleStructure* structure) {
    list->structures.push_back(structure);
    return *this;
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator =(
        NAngleStructureVector* vector) {
    list->structures.push_back(new NAngleStructure(owner, vector));
    return *this;
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator *() {
    return *this;
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator ++() {
    return *this;
}

inline NAngleStructureList::StructureInserter&
        NAngleStructureList::StructureInserter::operator ++(int) {
    return *this;
}

inline NAngleStructureList::Enumerator::Enumerator(NAngleStructureList* newList,
        NTriangulation* useTriang, NProgressManager* useManager) :
        list(newList), triang(useTriang), manager(useManager) {
}

} // namespace regina

#endif