1 /*
2  * The Doomsday Engine Project -- libcore
3  *
4  * Copyright © 2009-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
5  *
6  * @par License
7  * LGPL: http://www.gnu.org/licenses/lgpl.html
8  *
9  * <small>This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or (at your
12  * option) any later version. This program is distributed in the hope that it
13  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
15  * General Public License for more details. You should have received a copy of
16  * the GNU Lesser General Public License along with this program; if not, see:
17  * http://www.gnu.org/licenses</small>
18  */
19 
20 #ifndef LIBDENG2_ID_H
21 #define LIBDENG2_ID_H
22 
23 #include "../libcore.h"
24 #include "../ISerializable"
25 #include "../Value"
26 #include "../Log"
27 
28 namespace de {
29 
30 class String;
31 
32 /**
33  * Unique identifier number. Zero is not a valid identifier, as it reserved
34  * for the "no identifier" special case.
35  * @ingroup core
36  */
37 class DENG2_PUBLIC Id : public ISerializable, public LogEntry::Arg::Base
38 {
39 public:
40     typedef duint32 Type;
41 
42     /// The special "no identifier".
43     enum { None = 0 };
44 
45 public:
46     /**
47      * Constructs a new identifier. It is automatically unique (until the duint32 range
48      * is depleted).
49      */
50     Id();
51 
Id(Type const & idValue)52     Id(Type const &idValue) : _id(idValue) {}
53 
54     /**
55      * Constructs an identifier from the text representation.
56      *
57      * @param text  Text representation of an identifier, such as returned by asText().
58      */
59     Id(String const &text);
60 
61     ~Id();
62 
isNone()63     bool isNone() const { return _id == None; }
64 
65     bool operator < (Id const &other) const { return _id < other._id; }
66 
67     bool operator == (Id const &other) const { return _id == other._id; }
68 
69     bool operator != (Id const &other) const { return _id != other._id; }
70 
71     operator bool () const { return _id != None; }
72 
Type()73     operator Type () const { return _id; }
74 
75     /// Converts the Id to a text string.
76     operator String () const;
77 
78     operator Value::Number () const;
79 
80     /// Converts the Id to a text string, using the format "{id}".
81     String asText() const;
82 
83     ddouble asDouble() const;
84 
asUInt32()85     inline duint32 asUInt32() const { return _id; }
86 
87     dint64 asInt64() const;
88 
89     // Implements ISerializable.
90     void operator >> (Writer &to) const;
91     void operator << (Reader &from);
92 
93     // Implements LogEntry::Arg::Base.
logEntryArgType()94     LogEntry::Arg::Type logEntryArgType() const { return LogEntry::Arg::StringArgument; }
95 
96 public:
none()97     static Id none() { return Id::None; }
98 
99     static void resetGenerator(Type largestKnownId);
100 
101 private:
102     Type _id;
103 };
104 
105 DENG2_PUBLIC QTextStream &operator << (QTextStream &os, Id const &id);
106 
qHash(Id const & id)107 inline uint qHash(Id const &id) { return id; }
108 
109 /**
110  * Utility for declaring identifiers that are initially uninitialized.
111  */
112 class DENG2_PUBLIC NoneId : public Id
113 {
114 public:
NoneId()115     NoneId() : Id(None) {}
NoneId(Id const & other)116     NoneId(Id const &other) : Id(other) {}
117 };
118 
119 } // namespace de
120 
121 #endif // LIBDENG2_ID_H
122