Use an enumeration type rather than unnamed integers to specify the different types...
[synfig.git] / synfig-core / trunk / src / synfig / guid.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file guid.h
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_GUID_H
26 #define __SYNFIG_GUID_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include "string.h"
31 #include <stdint.h>
32 #include <cassert>
33
34 /* === M A C R O S ========================================================= */
35
36 /* === T Y P E D E F S ===================================================== */
37
38 /* === C L A S S E S & S T R U C T S ======================================= */
39
40 namespace synfig {
41
42 class GUID
43 {
44         union {
45                 struct {
46                         unsigned int a;
47                         unsigned int b;
48                         unsigned int c;
49                         unsigned int d;
50                 } u_32;
51                 struct {
52                         uint64_t a;
53                         uint64_t b;
54                 } u_64;
55
56         } data;
57
58 public:
59         GUID()
60                 { make_unique(); }
61         GUID(const GUID& x):data(x.data)
62                 { }
63         GUID(const int i){assert(!i); data.u_64.a=0;data.u_64.b=0;}
64
65         GUID(const String& str);
66
67         static GUID zero() { return GUID(0); }
68         static GUID hasher(const String& str);
69         static GUID hasher(int i);
70
71         operator bool()const { return data.u_32.a||data.u_32.b||data.u_32.c||data.u_32.d; }
72
73         uint64_t get_hi()const { return data.u_64.a; }
74         uint64_t get_lo()const { return data.u_64.b; }
75
76         uint64_t get_hi_hi()const { return data.u_32.a; }
77         uint64_t get_hi_lo()const { return data.u_32.b; }
78         uint64_t get_lo_hi()const { return data.u_32.c; }
79         uint64_t get_lo_lo()const { return data.u_32.d; }
80
81         void make_unique();
82         String get_string()const;
83
84         bool operator==(const GUID& rhs)const
85                 { return data.u_64.a==rhs.data.u_64.a && data.u_64.b==rhs.data.u_64.b; }
86         bool operator!=(const GUID& rhs)const
87                 { return data.u_64.a!=rhs.data.u_64.a || data.u_64.b!=rhs.data.u_64.b; }
88         bool operator<(const GUID& rhs)const
89                 { return (data.u_64.a==rhs.data.u_64.a)?(data.u_64.b<rhs.data.u_64.b):(data.u_64.a<rhs.data.u_64.a); }
90         bool operator>(const GUID& rhs)const
91                 { return (data.u_64.a==rhs.data.u_64.a)?(data.u_64.b>rhs.data.u_64.b):(data.u_64.a>rhs.data.u_64.a); }
92         bool operator<=(const GUID& rhs)const
93                 { return operator<(rhs) || operator==(rhs); }
94         bool operator>=(const GUID& rhs)const
95                 { return operator>(rhs) || operator==(rhs); }
96
97         //! Operator '^' (xor)
98         /*! If A ^ B == C, then C ^ B == A and B ^ A == C.
99         **      Also keep in mind that A ^ A == 0 and A ^ B ^ B = A. */
100         GUID& operator^=(const GUID& rhs)
101         {
102                 data.u_32.a^=rhs.data.u_32.a;
103                 data.u_32.b^=rhs.data.u_32.b;
104                 data.u_32.c^=rhs.data.u_32.c;
105                 data.u_32.d^=rhs.data.u_32.d;
106                 return *this;
107         }
108         GUID operator^(const GUID& rhs)const { return GUID(*this)^=rhs; }
109
110         //! Operator '%' (alt-xor)
111         /*! A % B != B % A. */
112         GUID& operator%=(const GUID& rhs)
113         {
114                 data.u_32.a^=rhs.data.u_32.b;
115                 data.u_32.b^=rhs.data.u_32.c;
116                 data.u_32.c^=rhs.data.u_32.d;
117                 data.u_32.d^=rhs.data.u_32.a;
118                 return *this;
119         }
120         GUID operator%(const GUID& rhs)const { return GUID(*this)%=rhs; }
121
122 };
123
124 class GUIDHash
125 {
126 public:
127         size_t operator()(const GUID& guid)const
128         {
129                 return
130                         guid.get_hi_hi()+
131                         guid.get_hi_lo()+
132                         guid.get_lo_hi()+
133                         guid.get_lo_lo();
134         }
135 };
136
137 };
138
139 /* === E N D =============================================================== */
140
141 #endif