| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -42,33 +42,33 @@ using CycleCount = int64_t;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					using SimulationTime = int64_t;
 | 
					 | 
					 | 
					 | 
					using SimulationTime = int64_t;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Helpers for simulation time.
 | 
					 | 
					 | 
					 | 
					// Helpers for simulation time.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime SecondsToSimulationTime(SimulationTime s)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime SecondsToSimulationTime(SimulationTime s)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return s * INT64_C(1000000000);
 | 
					 | 
					 | 
					 | 
					  return s * INT64_C(1000000000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime MillisecondsToSimulationTime(SimulationTime ms)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime MillisecondsToSimulationTime(SimulationTime ms)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ms * INT64_C(1000000);
 | 
					 | 
					 | 
					 | 
					  return ms * INT64_C(1000000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime MicrosecondsToSimulationTime(SimulationTime us)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime MicrosecondsToSimulationTime(SimulationTime us)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return us * INT64_C(1000);
 | 
					 | 
					 | 
					 | 
					  return us * INT64_C(1000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime SimulationTimeToSeconds(SimulationTime s)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime SimulationTimeToSeconds(SimulationTime s)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return s / INT64_C(1000000000);
 | 
					 | 
					 | 
					 | 
					  return s / INT64_C(1000000000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime SimulationTimeToMilliseconds(SimulationTime ms)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime SimulationTimeToMilliseconds(SimulationTime ms)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ms / INT64_C(1000000);
 | 
					 | 
					 | 
					 | 
					  return ms / INT64_C(1000000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime SimulationTimeToMicroseconds(SimulationTime us)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime SimulationTimeToMicroseconds(SimulationTime us)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return us / INT64_C(1000);
 | 
					 | 
					 | 
					 | 
					  return us / INT64_C(1000);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Calculates the difference between the specified timestamps, accounting for signed overflow.
 | 
					 | 
					 | 
					 | 
					// Calculates the difference between the specified timestamps, accounting for signed overflow.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr SimulationTime GetSimulationTimeDifference(SimulationTime prev, SimulationTime now)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr SimulationTime GetSimulationTimeDifference(SimulationTime prev, SimulationTime now)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (prev <= now)
 | 
					 | 
					 | 
					 | 
					  if (prev <= now)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return now - prev;
 | 
					 | 
					 | 
					 | 
					    return now - prev;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -78,111 +78,105 @@ constexpr SimulationTime GetSimulationTimeDifference(SimulationTime prev, Simula
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Zero-extending helper
 | 
					 | 
					 | 
					 | 
					// Zero-extending helper
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TReturn, typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TReturn, typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr TReturn ZeroExtend(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr TReturn ZeroExtend(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // auto unsigned_val = static_cast<typename std::make_unsigned<TValue>::type>(value);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // auto extended_val = static_cast<typename std::make_unsigned<TReturn>::type>(unsigned_val);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // return static_cast<TReturn>(extended_val);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<TReturn>(static_cast<typename std::make_unsigned<TReturn>::type>(
 | 
					 | 
					 | 
					 | 
					  return static_cast<TReturn>(static_cast<typename std::make_unsigned<TReturn>::type>(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static_cast<typename std::make_unsigned<TValue>::type>(value)));
 | 
					 | 
					 | 
					 | 
					    static_cast<typename std::make_unsigned<TValue>::type>(value)));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Sign-extending helper
 | 
					 | 
					 | 
					 | 
					// Sign-extending helper
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TReturn, typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TReturn, typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr TReturn SignExtend(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr TReturn SignExtend(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // auto signed_val = static_cast<typename std::make_signed<TValue>::type>(value);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // auto extended_val = static_cast<typename std::make_signed<TReturn>::type>(signed_val);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // return static_cast<TReturn>(extended_val);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<TReturn>(
 | 
					 | 
					 | 
					 | 
					  return static_cast<TReturn>(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static_cast<typename std::make_signed<TReturn>::type>(static_cast<typename std::make_signed<TValue>::type>(value)));
 | 
					 | 
					 | 
					 | 
					    static_cast<typename std::make_signed<TReturn>::type>(static_cast<typename std::make_signed<TValue>::type>(value)));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Type-specific helpers
 | 
					 | 
					 | 
					 | 
					// Type-specific helpers
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u16 ZeroExtend16(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u16 ZeroExtend16(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ZeroExtend<u16, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return ZeroExtend<u16, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u32 ZeroExtend32(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u32 ZeroExtend32(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ZeroExtend<u32, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return ZeroExtend<u32, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u64 ZeroExtend64(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u64 ZeroExtend64(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ZeroExtend<u64, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return ZeroExtend<u64, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u16 SignExtend16(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u16 SignExtend16(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return SignExtend<u16, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return SignExtend<u16, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u32 SignExtend32(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u32 SignExtend32(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return SignExtend<u32, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return SignExtend<u32, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u64 SignExtend64(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u64 SignExtend64(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return SignExtend<u64, TValue>(value);
 | 
					 | 
					 | 
					 | 
					  return SignExtend<u64, TValue>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u8 Truncate8(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u8 Truncate8(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u8>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
					 | 
					 | 
					 | 
					  return static_cast<u8>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u16 Truncate16(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u16 Truncate16(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u16>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
					 | 
					 | 
					 | 
					  return static_cast<u16>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u32 Truncate32(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u32 Truncate32(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u32>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
					 | 
					 | 
					 | 
					  return static_cast<u32>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// BCD helpers
 | 
					 | 
					 | 
					 | 
					// BCD helpers
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u8 DecimalToBCD(u8 value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u8 DecimalToBCD(u8 value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ((value / 10) << 4) + (value % 10);
 | 
					 | 
					 | 
					 | 
					  return ((value / 10) << 4) + (value % 10);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u8 BCDToDecimal(u8 value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u8 BCDToDecimal(u8 value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return ((value >> 4) * 10) + (value % 16);
 | 
					 | 
					 | 
					 | 
					  return ((value >> 4) * 10) + (value % 16);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Boolean to integer
 | 
					 | 
					 | 
					 | 
					// Boolean to integer
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u8 BoolToUInt8(bool value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u8 BoolToUInt8(bool value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u8>(value);
 | 
					 | 
					 | 
					 | 
					  return static_cast<u8>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u16 BoolToUInt16(bool value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u16 BoolToUInt16(bool value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u16>(value);
 | 
					 | 
					 | 
					 | 
					  return static_cast<u16>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u32 BoolToUInt32(bool value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u32 BoolToUInt32(bool value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u32>(value);
 | 
					 | 
					 | 
					 | 
					  return static_cast<u32>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr u64 BoolToUInt64(bool value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr u64 BoolToUInt64(bool value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<u64>(value);
 | 
					 | 
					 | 
					 | 
					  return static_cast<u64>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Integer to boolean
 | 
					 | 
					 | 
					 | 
					// Integer to boolean
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr bool ConvertToBool(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr bool ConvertToBool(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return static_cast<bool>(value);
 | 
					 | 
					 | 
					 | 
					  return static_cast<bool>(value);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Unsafe integer to boolean
 | 
					 | 
					 | 
					 | 
					// Unsafe integer to boolean
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
					 | 
					 | 
					 | 
					template<typename TValue>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr bool ConvertToBoolUnchecked(TValue value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr bool ConvertToBoolUnchecked(TValue value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // static_assert(sizeof(uint8) == sizeof(bool));
 | 
					 | 
					 | 
					 | 
					  // static_assert(sizeof(uint8) == sizeof(bool));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  bool ret;
 | 
					 | 
					 | 
					 | 
					  bool ret;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -192,7 +186,7 @@ constexpr bool ConvertToBoolUnchecked(TValue value)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Generic sign extension
 | 
					 | 
					 | 
					 | 
					// Generic sign extension
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					template<int NBITS, typename T>
 | 
					 | 
					 | 
					 | 
					template<int NBITS, typename T>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					constexpr T SignExtendN(T value)
 | 
					 | 
					 | 
					 | 
					ALWAYS_INLINE constexpr T SignExtendN(T value)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
 | 
					 | 
					 | 
					 | 
					  // http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  constexpr int shift = 8 * sizeof(T) - NBITS;
 | 
					 | 
					 | 
					 | 
					  constexpr int shift = 8 * sizeof(T) - NBITS;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -201,38 +195,38 @@ constexpr T SignExtendN(T value)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Enum class bitwise operators
 | 
					 | 
					 | 
					 | 
					// Enum class bitwise operators
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(type_)                                                                  \
 | 
					 | 
					 | 
					 | 
					#define IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(type_)                                                                  \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_ operator&(type_ lhs, type_ rhs)                                                               \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_ operator&(type_ lhs, type_ rhs)                                                               \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) &                                    \
 | 
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) &                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_ operator|(type_ lhs, type_ rhs)                                                               \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_ operator|(type_ lhs, type_ rhs)                                                               \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) |                                    \
 | 
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) |                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_ operator^(type_ lhs, type_ rhs)                                                               \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_ operator^(type_ lhs, type_ rhs)                                                               \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^                                    \
 | 
					 | 
					 | 
					 | 
					    return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
					 | 
					 | 
					 | 
					                              static_cast<std::underlying_type<type_>::type>(rhs));                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_ operator~(type_ val)                                                                          \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_ operator~(type_ val)                                                                          \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return static_cast<type_>(~static_cast<std::underlying_type<type_>::type>(val));                                   \
 | 
					 | 
					 | 
					 | 
					    return static_cast<type_>(~static_cast<std::underlying_type<type_>::type>(val));                                   \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_& operator&=(type_& lhs, type_ rhs)                                                            \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_& operator&=(type_& lhs, type_ rhs)                                                            \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) &                                     \
 | 
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) &                                     \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return lhs;                                                                                                        \
 | 
					 | 
					 | 
					 | 
					    return lhs;                                                                                                        \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_& operator|=(type_& lhs, type_ rhs)                                                            \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_& operator|=(type_& lhs, type_ rhs)                                                            \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) |                                     \
 | 
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) |                                     \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return lhs;                                                                                                        \
 | 
					 | 
					 | 
					 | 
					    return lhs;                                                                                                        \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  }                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  inline constexpr type_& operator^=(type_& lhs, type_ rhs)                                                            \
 | 
					 | 
					 | 
					 | 
					  ALWAYS_INLINE constexpr type_& operator^=(type_& lhs, type_ rhs)                                                            \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
					 | 
					 | 
					 | 
					  {                                                                                                                    \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^                                     \
 | 
					 | 
					 | 
					 | 
					    lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^                                     \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
					 | 
					 | 
					 | 
					                             static_cast<std::underlying_type<type_>::type>(rhs));                                     \
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |