TRLC Platform Library  1.0.0
Header-only C++ library for compile-time platform detection and abstraction
typeinfo.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstddef> // For size_t
4 #include <type_traits> // For standard type traits
5 
6 // Forward declarations to avoid circular dependencies
7 namespace trlc {
8 namespace platform {
9 namespace detail {
10 // detectCacheLineSize() is defined in architecture.hpp
11 constexpr size_t detectPageSize() noexcept;
12 } // namespace detail
13 } // namespace platform
14 } // namespace trlc
15 
40 #include <cstddef>
41 #include <cstdint>
42 #include <type_traits>
43 
44 namespace trlc {
45 namespace platform {
46 
47 //==============================================================================
48 // Forward Declarations
49 //==============================================================================
50 
51 namespace detail {
52 // Helper functions for compile-time calculations
53 template <typename Type>
54 constexpr size_t calculateTypePadding() noexcept;
55 
56 template <typename Type>
57 constexpr bool hasTypePadding() noexcept;
58 
59 // Platform-specific page size detection (cache line size is in architecture.hpp)
60 constexpr size_t detectPageSize() noexcept;
61 } // namespace detail
62 
63 //==============================================================================
64 // Core Type Information Functions
65 //==============================================================================
66 
83 template <typename Type>
84 constexpr size_t getTypeSize() noexcept {
85  return sizeof(Type);
86 }
87 
103 template <typename Type>
104 constexpr size_t getTypeAlignment() noexcept {
105  return alignof(Type);
106 }
107 
119 constexpr size_t getCacheLineSize() noexcept {
120  // Inline implementation to avoid circular dependency with architecture.hpp
121 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
122  return 64; // x86/x64 typical cache line size
123 #elif defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM)
124  return 64; // ARM typical cache line size
125 #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
126  return 128; // PowerPC typical cache line size
127 #else
128  return 64; // Conservative default
129 #endif
130 }
131 
143 constexpr size_t getPageSize() noexcept {
144  return detail::detectPageSize();
145 }
146 
147 //==============================================================================
148 // Type Information Structure
149 //==============================================================================
150 
167 template <typename Type>
168 struct TypeInfo {
170  static constexpr size_t size = sizeof(Type);
171 
173  static constexpr size_t alignment = alignof(Type);
174 
176  static constexpr bool is_cache_line_aligned = (alignment >= getCacheLineSize());
177 
179  static constexpr bool is_trivially_copyable = std::is_trivially_copyable_v<Type>;
180 
182  static constexpr bool is_standard_layout = std::is_standard_layout_v<Type>;
183 
185  static constexpr bool is_pod = is_trivially_copyable && is_standard_layout;
186 
188  static constexpr bool is_empty = std::is_empty_v<Type>;
189 
191  static constexpr bool is_fundamental = std::is_fundamental_v<Type>;
192 
194  static constexpr bool is_integral = std::is_integral_v<Type>;
195 
197  static constexpr bool is_floating_point = std::is_floating_point_v<Type>;
198 
200  static constexpr bool is_pointer = std::is_pointer_v<Type>;
201 
203  static constexpr bool is_array = std::is_array_v<Type>;
204 };
205 
206 //==============================================================================
207 // Padding Analysis Functions
208 //==============================================================================
209 
229 template <typename Type>
230 constexpr size_t calculatePadding() noexcept {
231  return detail::calculateTypePadding<Type>();
232 }
233 
253 template <typename Type>
254 constexpr bool hasInternalPadding() noexcept {
255  return detail::hasTypePadding<Type>();
256 }
257 
258 //==============================================================================
259 // Alignment Helper Types
260 //==============================================================================
261 
275 template <size_t TAlignment>
276 struct AlignedType {
277  static_assert(TAlignment > 0, "Alignment must be greater than zero");
278  static_assert((TAlignment & (TAlignment - 1)) == 0, "Alignment must be a power of two");
279 
281  alignas(TAlignment) char data[TAlignment];
282 
284  void* get() noexcept { return data; }
285 
287  const void* get() const noexcept { return data; }
288 
290  template <typename T>
291  T* as() noexcept {
292  static_assert(alignof(T) <= TAlignment, "Type alignment exceeds storage alignment");
293  return reinterpret_cast<T*>(data);
294  }
295 
297  template <typename T>
298  const T* as() const noexcept {
299  static_assert(alignof(T) <= TAlignment, "Type alignment exceeds storage alignment");
300  return reinterpret_cast<const T*>(data);
301  }
302 };
303 
317 using CacheLineAligned = AlignedType<64>; // Most common cache line size
318 
331 using PageAligned = AlignedType<4096>; // Most common page size
332 
333 //==============================================================================
334 // Memory Layout Verification Functions
335 //==============================================================================
336 
354 template <typename Type, size_t TExpectedSize>
355 constexpr bool verifyTypeSize() noexcept {
356  return sizeof(Type) == TExpectedSize;
357 }
358 
375 template <typename Type, size_t TExpectedAlignment>
376 constexpr bool verifyTypeAlignment() noexcept {
377  return alignof(Type) == TExpectedAlignment;
378 }
379 
388 template <typename Type>
389 constexpr bool isCacheLineAligned() noexcept {
390  return alignof(Type) >= getCacheLineSize();
391 }
392 
401 template <typename Type>
402 constexpr bool isPageAligned() noexcept {
403  return alignof(Type) >= getPageSize();
404 }
405 
406 //==============================================================================
407 // Size and Alignment Calculation Utilities
408 //==============================================================================
409 
419 constexpr size_t alignedSize(size_t size, size_t alignment) noexcept {
420  return (size + alignment - 1) & ~(alignment - 1);
421 }
422 
432 constexpr uintptr_t alignedAddress(uintptr_t addr, size_t alignment) noexcept {
433  return (addr + alignment - 1) & ~(alignment - 1);
434 }
435 
443 constexpr bool isAligned(uintptr_t addr, size_t alignment) noexcept {
444  return (addr & (alignment - 1)) == 0;
445 }
446 
456 inline bool isAligned(const void* ptr, size_t alignment) noexcept {
457  return isAligned(reinterpret_cast<uintptr_t>(ptr), alignment);
458 }
459 
460 //==============================================================================
461 // Implementation Details
462 //==============================================================================
463 
464 namespace detail {
465 
474 template <typename Type>
475 constexpr size_t calculateTypePadding() noexcept {
476  if constexpr (std::is_fundamental_v<Type> || std::is_pointer_v<Type>) {
477  // Fundamental types and pointers typically have no internal padding
478  return 0;
479  } else if constexpr (std::is_empty_v<Type>) {
480  // Empty types have no padding
481  return 0;
482  } else {
483  // For other types, we can only estimate
484  // The actual padding calculation would require reflection or compiler intrinsics
485  // For now, we assume minimal padding based on alignment
486  constexpr size_t type_size = sizeof(Type);
487  constexpr size_t type_alignment = alignof(Type);
488 
489  // If size is not a multiple of alignment, there's likely trailing padding
490  return (type_alignment - (type_size % type_alignment)) % type_alignment;
491  }
492 }
493 
497 template <typename Type>
498 constexpr bool hasTypePadding() noexcept {
499  return calculateTypePadding<Type>() > 0;
500 }
501 
502 // Note: detectCacheLineSize() is defined in architecture.hpp to avoid duplication
503 
510 constexpr size_t detectPageSize() noexcept {
511  // Platform-specific detection
512 #if defined(_WIN32) || defined(_WIN64)
513  // Windows typically uses 4KB pages (though large pages are possible)
514  return 4096;
515 #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
516  defined(__OpenBSD__)
517  // Most Unix-like systems use 4KB pages by default
518  return 4096;
519 #elif defined(__sparc__)
520  // SPARC systems often use 8KB pages
521  return 8192;
522 #elif defined(__ia64__)
523  // Itanium systems often use 16KB pages
524  return 16384;
525 #else
526  // Conservative default for unknown platforms
527  return 4096;
528 #endif
529 }
530 
531 } // namespace detail
532 
533 } // namespace platform
534 } // namespace trlc
535 
536 //==============================================================================
537 // Utility Macros
538 //==============================================================================
539 
546 #define TRLC_ALIGNOF(type) (alignof(type))
547 
554 #define TRLC_SIZEOF(type) (sizeof(type))
555 
561 #define TRLC_CACHE_LINE_SIZE (trlc::platform::getCacheLineSize())
562 
568 #define TRLC_PAGE_SIZE (trlc::platform::getPageSize())
569 
585 #define TRLC_ALIGN_TO_CACHE_LINE alignas(trlc::platform::getCacheLineSize())
586 
593 #define TRLC_ALIGN_TO_PAGE alignas(trlc::platform::getPageSize())
594 
603 // Note: TRLC_CACHE_ALIGNED is defined in macros.hpp
604 
613 #define TRLC_PAGE_ALIGNED(type, name) TRLC_ALIGN_TO_PAGE type name
614 
615 //==============================================================================
616 // Static Assertions for Compile-Time Validation
617 //==============================================================================
618 
619 // Verify that our alignment helpers work correctly
620 static_assert(alignof(trlc::platform::CacheLineAligned) >= 64,
621  "CacheLineAligned should be at least 64-byte aligned");
622 static_assert(alignof(trlc::platform::PageAligned) >= 4096,
623  "PageAligned should be at least 4096-byte aligned");
624 
625 // Verify that our size functions work
626 static_assert(trlc::platform::getTypeSize<char>() == 1, "char should be 1 byte");
627 static_assert(trlc::platform::getTypeAlignment<char>() == 1, "char should be 1-byte aligned");
628 
629 // Verify that our verification functions work
630 static_assert(trlc::platform::verifyTypeSize<char, 1>(), "Type size verification should work");
631 static_assert(trlc::platform::verifyTypeAlignment<char, 1>(),
632  "Type alignment verification should work");
633 
634 // Verify TypeInfo works correctly
635 static_assert(trlc::platform::TypeInfo<int>::size == sizeof(int),
636  "TypeInfo size should match sizeof");
637 static_assert(trlc::platform::TypeInfo<int>::alignment == alignof(int),
638  "TypeInfo alignment should match alignof");
639 static_assert(trlc::platform::TypeInfo<int>::is_fundamental, "int should be fundamental");
640 static_assert(trlc::platform::TypeInfo<int>::is_integral, "int should be integral");
642  "int should not be floating point");
static size_t calculateTypePadding()
Calculate padding for a type (implementation detail)
Definition: typeinfo.hpp:475
static bool hasTypePadding()
Check if a type has padding (implementation detail)
Definition: typeinfo.hpp:498
static size_t detectPageSize()
Detect page size (implementation detail)
Definition: typeinfo.hpp:510
static size_t getPageSize()
Get the page size for the current platform.
Definition: typeinfo.hpp:143
static size_t getTypeAlignment()
Definition: typeinfo.hpp:104
static size_t getTypeSize()
Definition: typeinfo.hpp:84
static bool isPageAligned()
Verify that a type is suitably aligned for page boundaries.
Definition: typeinfo.hpp:402
static bool isCacheLineAligned()
Verify that a type is suitably aligned for cache line optimization.
Definition: typeinfo.hpp:389
static bool isAligned(uintptr_t addr, size_t alignment)
Check if an address is aligned to the specified boundary.
Definition: typeinfo.hpp:443
static size_t alignedSize(size_t size, size_t alignment)
Calculate the aligned size for a given alignment.
Definition: typeinfo.hpp:419
static bool hasInternalPadding()
Definition: typeinfo.hpp:254
static size_t getCacheLineSize()
Get the cache line size for the current platform.
Definition: typeinfo.hpp:119
static bool verifyTypeSize()
Definition: typeinfo.hpp:355
static uintptr_t alignedAddress(uintptr_t addr, size_t alignment)
Calculate the aligned address for a given alignment.
Definition: typeinfo.hpp:432
static size_t calculatePadding()
Definition: typeinfo.hpp:230
static bool verifyTypeAlignment()
Definition: typeinfo.hpp:376
const T * as() const
Get a const typed pointer to the aligned storage.
Definition: typeinfo.hpp:298
void * get()
Get a pointer to the aligned storage.
Definition: typeinfo.hpp:284
const void * get() const
Get a const pointer to the aligned storage.
Definition: typeinfo.hpp:287
T * as()
Get a typed pointer to the aligned storage.
Definition: typeinfo.hpp:291