PLYwoot
Header-only C++17 library for parsing and writing PLY files
Loading...
Searching...
No Matches
type_traits.hpp
Go to the documentation of this file.
1/*
2 This file is part of PLYwoot, a header-only PLY parser.
3
4 Copyright (C) 2023-2025, Ton van den Heuvel
5
6 PLYwoot is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef PLYWOOT_TYPE_TRAITS_HPP
21#define PLYWOOT_TYPE_TRAITS_HPP
22
24
25#include "reflect.hpp"
26#include "std.hpp"
27#include "types.hpp"
28
29#include <algorithm>
30#include <type_traits>
31
32namespace plywoot::detail {
33
36template<typename T>
37struct IsList
38{
39 static constexpr bool value = false;
40};
41
42template<typename T, std::size_t N>
43struct IsList<reflect::Array<T, N>>
44{
45 static constexpr bool value = true;
46};
47
48template<typename T>
49struct IsList<std::vector<T>>
50{
51 static constexpr bool value = true;
52};
53
54template<typename T>
55struct IsList<reflect::Type<T>>
56{
57 static constexpr bool value = IsList<T>::value;
58};
60
65template<typename T>
66constexpr bool isList()
67{
68 return IsList<T>::value;
69}
70
75template<typename... Ts>
76struct NumProperties
77{
78 static constexpr std::size_t size = 0;
79};
80
81template<typename T, typename... Ts>
82struct NumProperties<T, Ts...>
83{
84 static constexpr std::size_t size = NumProperties<T>::size + NumProperties<Ts...>::size;
85};
86
87template<typename T, std::size_t N>
88struct NumProperties<reflect::Array<T, N>>
89{
90 static constexpr std::size_t size = 1;
91};
92
93template<typename T, std::size_t N>
94struct NumProperties<reflect::Pack<T, N>>
95{
96 static constexpr std::size_t size = N;
97};
98
99template<typename T>
100struct NumProperties<reflect::Stride<T>>
101{
102 static constexpr std::size_t size = 0;
103};
104
105template<typename T>
106struct NumProperties<T>
107{
108 static constexpr std::size_t size = 1;
109};
110
117template<typename... Ts>
118constexpr std::size_t numProperties()
119{
120 return NumProperties<Ts...>::size;
121}
122
129template<typename T>
130constexpr bool isSame(PlyDataType type)
131{
132 switch (type)
133 {
134 case PlyDataType::Char:
135 return std::is_same<T, char>::value;
136 case PlyDataType::UChar:
137 return std::is_same<T, unsigned char>::value;
138 case PlyDataType::Short:
139 return std::is_same<T, short>::value;
140 case PlyDataType::UShort:
141 return std::is_same<T, unsigned short>::value;
142 case PlyDataType::Int:
143 return std::is_same<T, int>::value;
144 case PlyDataType::UInt:
145 return std::is_same<T, unsigned int>::value;
146 case PlyDataType::Float:
147 return std::is_same<T, float>::value;
148 case PlyDataType::Double:
149 return std::is_same<T, double>::value;
150 }
151
152 return false;
153}
154
158template<typename T>
159struct IsPack
160{
161 static constexpr bool value = false;
162};
163
164template<typename T, std::size_t N>
165struct IsPack<reflect::Pack<T, N>>
166{
167 static constexpr bool value = true;
168};
170
177template<typename T, typename... Ts>
178struct SizeOf
179{
180 static constexpr auto size = SizeOf<T>::size + SizeOf<Ts...>::size;
181};
182
183template<typename T>
184struct SizeOf<T>
185{
186 static constexpr auto size = sizeof(T);
187};
188
189template<typename T, std::size_t N>
190struct SizeOf<reflect::Array<T, N>>
191{
192 static constexpr auto size = N * SizeOf<T>::size;
193};
194
195template<typename T, std::size_t N>
196struct SizeOf<reflect::Pack<T, N>>
197{
198 static constexpr auto size = N * SizeOf<T>::size;
199};
201
210template<typename... Ts>
211constexpr std::size_t sizeOf()
212{
213 return SizeOf<Ts...>::size;
214}
215
220constexpr std::size_t sizeOf(PlyDataType type)
221{
222 switch (type)
223 {
224 case PlyDataType::Char:
225 case PlyDataType::UChar:
226 return 1;
227 case PlyDataType::Short:
228 case PlyDataType::UShort:
229 return 2;
230 case PlyDataType::Int:
231 case PlyDataType::UInt:
232 case PlyDataType::Float:
233 return 4;
234 case PlyDataType::Double:
235 return 8;
236 }
237
238 return 0;
239}
240
248template<typename Ptr>
249constexpr Ptr align(Ptr ptr, PlyDataType type)
250{
251 switch (type)
252 {
253 case PlyDataType::Char:
254 return detail::align(ptr, alignof(char));
255 case PlyDataType::UChar:
256 return detail::align(ptr, alignof(unsigned char));
257 case PlyDataType::Short:
258 return detail::align(ptr, alignof(short));
259 case PlyDataType::UShort:
260 return detail::align(ptr, alignof(unsigned short));
261 case PlyDataType::Int:
262 return detail::align(ptr, alignof(int));
263 case PlyDataType::UInt:
264 return detail::align(ptr, alignof(unsigned int));
265 case PlyDataType::Float:
266 return detail::align(ptr, alignof(float));
267 case PlyDataType::Double:
268 return detail::align(ptr, alignof(double));
269 }
270
271 return ptr;
272}
273
282template<typename T>
283constexpr bool isPacked(uintptr_t offset = 0)
284{
285 return (offset % alignof(T)) == 0;
286}
287
294template<typename T, typename U, typename... Ts>
295constexpr bool isPacked(uintptr_t offset = 0)
296{
297 return (offset % alignof(T)) == 0 && isPacked<U, Ts...>(offset + sizeOf<T>());
298}
299
307template<typename... Ts>
308constexpr bool isTriviallyCopyable()
309{
310 return (std::is_trivially_copyable_v<Ts> && ...);
311}
312
317template<typename T>
318struct IsMemcpyable
319{
320 bool operator()(const PlyPropertyConstIterator first, const PlyPropertyConstIterator last) const
321 {
322 return first < last && isSame<T>(first->type());
323 }
324};
325
326template<typename T, std::size_t N>
327struct IsMemcpyable<reflect::Array<T, N>>
328{
329 bool operator()(const PlyPropertyConstIterator, const PlyPropertyConstIterator) const { return false; }
330};
332
333template<typename T, std::size_t N>
334struct IsMemcpyable<reflect::Pack<T, N>>
335{
336 bool operator()(const PlyPropertyConstIterator first, const PlyPropertyConstIterator last) const
337 {
338 return first + N <= last &&
339 std::all_of(first, first + N, [](const PlyProperty &p) { return isSame<T>(p.type()); });
340 }
341};
342
354template<typename T>
356{
357 return first + detail::numProperties<T>() == last && IsMemcpyable<T>{}(first, last);
358}
359
371template<typename T, typename U, typename... Ts>
373{
374 return IsMemcpyable<T>{}(first, last) && isMemcpyable<U, Ts...>(first + detail::numProperties<T>(), last);
375}
376
377}
378
379#endif
constexpr Ptr align(Ptr ptr, std::size_t alignment)
Definition std.hpp:50
constexpr bool isTriviallyCopyable()
constexpr std::size_t numProperties()
constexpr bool isPacked(uintptr_t offset=0)
constexpr std::size_t sizeOf()
bool isMemcpyable(const PlyPropertyConstIterator first, const PlyPropertyConstIterator last)
constexpr bool isSame(PlyDataType type)
constexpr bool isList()
std::vector< PlyProperty >::const_iterator PlyPropertyConstIterator
Definition types.hpp:145
PlyDataType
Enumeration of data types supported by the PLY format.
Definition types.hpp:36