1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
25 **************************************************************************/
27 // File: vogl_packed_uint
30 #include "vogl_core.h"
34 // N must range from [1,8]
35 template <uint N, bool big_endian = true>
38 typedef typename template_if<(N > sizeof(uint32)), uint64_t, uint32>::result param_type;
42 VOGL_ASSUME((N >= 1) && (N <= 8));
45 inline packed_uint(param_type val)
47 VOGL_ASSUME((N >= 1) && (N <= 8));
51 inline packed_uint(const packed_uint &other)
53 VOGL_ASSUME((N >= 1) && (N <= 8));
57 inline packed_uint &operator=(const packed_uint &rhs)
60 memcpy(m_buf, rhs.m_buf, sizeof(m_buf));
64 inline packed_uint &operator=(param_type val)
68 for (uint i = 0; i < N; ++i, val >>= 8U)
69 m_buf[(N - 1) - i] = static_cast<uint8>(val);
73 for (uint i = 0; i < N; ++i, val >>= 8U)
74 m_buf[i] = static_cast<uint8>(val);
82 inline uint64_t get_uint64() const
85 for (uint i = 0; i < N; ++i)
88 val |= m_buf[big_endian ? i : ((N - 1) - i)];
93 inline uint32 get_uint32() const
96 for (uint i = 0; i < N; ++i)
99 val |= m_buf[big_endian ? i : ((N - 1) - i)];
104 inline uint16 get_uint16() const
107 for (uint i = 0; i < N; ++i)
110 val |= m_buf[big_endian ? i : ((N - 1) - i)];
115 inline operator param_type() const
117 return static_cast<param_type>((sizeof(param_type) <= sizeof(uint32)) ? get_uint32() : get_uint64());
120 inline packed_uint &byte_swap()
122 for (uint i = 0; i < (N / 2); i++)
123 std::swap(m_buf[i], m_buf[(N - 1) - i]);
130 inline void packed_uint_test()
132 packed_uint<8, true> q0;
133 q0 = 0x123456789ABCDEF0ULL;
135 VOGL_VERIFY(k0 == 0x123456789ABCDEF0ULL);
136 VOGL_VERIFY(q0.m_buf[0] == 0x12);
138 packed_uint<8, false> q1;
139 q1 = 0x123456789ABCDEF0ULL;
141 VOGL_VERIFY(k1 == 0x123456789ABCDEF0ULL);
142 VOGL_VERIFY(q1.m_buf[0] == 0xF0);
144 packed_uint<4, true> q2;
147 VOGL_VERIFY(k2 == 0xDEADBEEF);
148 VOGL_VERIFY(q2.m_buf[0] == 0xDE);
150 packed_uint<4, false> q3;
153 VOGL_VERIFY(k3 == 0xDEADBEEF);
154 VOGL_VERIFY(q3.m_buf[0] == 0xEF);
156 packed_uint<3, true> q8;
159 VOGL_VERIFY(k8 == 0xDEADBE);
160 VOGL_VERIFY(q8.m_buf[0] == 0xDE);
162 packed_uint<3, false> q9;
165 VOGL_VERIFY(k9 == 0xDEADBE);
166 VOGL_VERIFY(q9.m_buf[0] == 0xBE);
168 packed_uint<2, true> q4;
171 VOGL_VERIFY(k4 == 0xDEAD);
172 VOGL_VERIFY(q4.m_buf[0] == 0xDE);
174 packed_uint<2, false> q5;
177 VOGL_VERIFY(k5 == 0xDEAD);
178 VOGL_VERIFY(q5.m_buf[0] == 0xAD);
180 packed_uint<1, true> q6;
183 VOGL_VERIFY(k6 == 0xDE);
184 VOGL_VERIFY(q6.m_buf[0] == 0xDE);
186 packed_uint<1, false> q7;
189 VOGL_VERIFY(k7 == 0xDE);
190 VOGL_VERIFY(q7.m_buf[0] == 0xDE);
193 for (uint64_t i = 0; i <= 0xFFFFFFFFU; i++)
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);