]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_packed_uint.h
Initial vogl checkin
[vogl] / src / voglcore / vogl_packed_uint.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_packed_uint
28 #pragma once
29
30 #include "vogl_core.h"
31
32 namespace vogl
33 {
34     // N must range from [1,8]
35     template <uint N, bool big_endian = true>
36     struct packed_uint
37     {
38         typedef typename template_if<(N > sizeof(uint32)), uint64_t, uint32>::result param_type;
39
40         inline packed_uint()
41         {
42             VOGL_ASSUME((N >= 1) && (N <= 8));
43         }
44
45         inline packed_uint(param_type val)
46         {
47             VOGL_ASSUME((N >= 1) && (N <= 8));
48             *this = val;
49         }
50
51         inline packed_uint(const packed_uint &other)
52         {
53             VOGL_ASSUME((N >= 1) && (N <= 8));
54             *this = other;
55         }
56
57         inline packed_uint &operator=(const packed_uint &rhs)
58         {
59             if (this != &rhs)
60                 memcpy(m_buf, rhs.m_buf, sizeof(m_buf));
61             return *this;
62         }
63
64         inline packed_uint &operator=(param_type val)
65         {
66             if (big_endian)
67             {
68                 for (uint i = 0; i < N; ++i, val >>= 8U)
69                     m_buf[(N - 1) - i] = static_cast<uint8>(val);
70             }
71             else
72             {
73                 for (uint i = 0; i < N; ++i, val >>= 8U)
74                     m_buf[i] = static_cast<uint8>(val);
75             }
76
77             VOGL_ASSERT(!val);
78
79             return *this;
80         }
81
82         inline uint64_t get_uint64() const
83         {
84             uint64_t val = 0;
85             for (uint i = 0; i < N; ++i)
86             {
87                 val <<= 8U;
88                 val |= m_buf[big_endian ? i : ((N - 1) - i)];
89             }
90             return val;
91         }
92
93         inline uint32 get_uint32() const
94         {
95             uint32 val = 0;
96             for (uint i = 0; i < N; ++i)
97             {
98                 val <<= 8U;
99                 val |= m_buf[big_endian ? i : ((N - 1) - i)];
100             }
101             return val;
102         }
103
104         inline uint16 get_uint16() const
105         {
106             uint16 val = 0;
107             for (uint i = 0; i < N; ++i)
108             {
109                 val <<= 8U;
110                 val |= m_buf[big_endian ? i : ((N - 1) - i)];
111             }
112             return val;
113         }
114
115         inline operator param_type() const
116         {
117             return static_cast<param_type>((sizeof(param_type) <= sizeof(uint32)) ? get_uint32() : get_uint64());
118         }
119
120         inline packed_uint &byte_swap()
121         {
122             for (uint i = 0; i < (N / 2); i++)
123                 std::swap(m_buf[i], m_buf[(N - 1) - i]);
124             return *this;
125         }
126
127         uint8 m_buf[N];
128     };
129
130     inline void packed_uint_test()
131     {
132         packed_uint<8, true> q0;
133         q0 = 0x123456789ABCDEF0ULL;
134         uint64_t k0 = q0;
135         VOGL_VERIFY(k0 == 0x123456789ABCDEF0ULL);
136         VOGL_VERIFY(q0.m_buf[0] == 0x12);
137
138         packed_uint<8, false> q1;
139         q1 = 0x123456789ABCDEF0ULL;
140         uint64_t k1 = q1;
141         VOGL_VERIFY(k1 == 0x123456789ABCDEF0ULL);
142         VOGL_VERIFY(q1.m_buf[0] == 0xF0);
143
144         packed_uint<4, true> q2;
145         q2 = 0xDEADBEEF;
146         uint32 k2 = q2;
147         VOGL_VERIFY(k2 == 0xDEADBEEF);
148         VOGL_VERIFY(q2.m_buf[0] == 0xDE);
149
150         packed_uint<4, false> q3;
151         q3 = 0xDEADBEEF;
152         uint32 k3 = q3;
153         VOGL_VERIFY(k3 == 0xDEADBEEF);
154         VOGL_VERIFY(q3.m_buf[0] == 0xEF);
155
156         packed_uint<3, true> q8;
157         q8 = 0xDEADBE;
158         uint32 k8 = q8;
159         VOGL_VERIFY(k8 == 0xDEADBE);
160         VOGL_VERIFY(q8.m_buf[0] == 0xDE);
161
162         packed_uint<3, false> q9;
163         q9 = 0xDEADBE;
164         uint32 k9 = q9;
165         VOGL_VERIFY(k9 == 0xDEADBE);
166         VOGL_VERIFY(q9.m_buf[0] == 0xBE);
167
168         packed_uint<2, true> q4;
169         q4 = 0xDEAD;
170         uint32 k4 = q4;
171         VOGL_VERIFY(k4 == 0xDEAD);
172         VOGL_VERIFY(q4.m_buf[0] == 0xDE);
173
174         packed_uint<2, false> q5;
175         q5 = 0xDEAD;
176         uint32 k5 = q5;
177         VOGL_VERIFY(k5 == 0xDEAD);
178         VOGL_VERIFY(q5.m_buf[0] == 0xAD);
179
180         packed_uint<1, true> q6;
181         q6 = 0xDE;
182         uint32 k6 = q6;
183         VOGL_VERIFY(k6 == 0xDE);
184         VOGL_VERIFY(q6.m_buf[0] == 0xDE);
185
186         packed_uint<1, false> q7;
187         q7 = 0xDE;
188         uint32 k7 = q7;
189         VOGL_VERIFY(k7 == 0xDE);
190         VOGL_VERIFY(q7.m_buf[0] == 0xDE);
191
192 #if 0
193         for (uint64_t i = 0; i <= 0xFFFFFFFFU; i++)
194         {
195                 packed_uint<4, true> b(static_cast<uint32>(i));
196                 packed_uint<4, true> l(static_cast<uint32>(i));
197                 VOGL_VERIFY((b == i) && (l == i));
198                 if ((i & 4095) == 4095) printf("0x%04X\n", i);
199         }
200 #endif
201     }
202
203 } // namespace vogl