mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-11-04 00:16:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			46 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			46 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
//  DeferredValue.hpp
 | 
						|
//  Clock Signal
 | 
						|
//
 | 
						|
//  Created by Thomas Harte on 07/08/2021.
 | 
						|
//  Copyright © 2021 Thomas Harte. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
/*!
 | 
						|
	Provides storage for a single deferred value: one with a current value and a certain number
 | 
						|
	of future values.
 | 
						|
*/
 | 
						|
template <int DeferredDepth, typename ValueT> class DeferredValue {
 | 
						|
private:
 | 
						|
	static_assert(sizeof(ValueT) <= 4);
 | 
						|
 | 
						|
	static constexpr int elements_per_uint32 = sizeof(uint32_t) / sizeof(ValueT);
 | 
						|
	static constexpr int unit_shift = sizeof(ValueT) * 8;
 | 
						|
	static constexpr int insert_shift = (DeferredDepth & (elements_per_uint32 - 1)) * unit_shift;
 | 
						|
	static constexpr uint32_t insert_mask = ~(0xffff'ffff << insert_shift);
 | 
						|
 | 
						|
	std::array<uint32_t, (DeferredDepth + elements_per_uint32 - 1) / elements_per_uint32> backlog;
 | 
						|
 | 
						|
public:
 | 
						|
	/// @returns the current value.
 | 
						|
	ValueT value() const {
 | 
						|
		return uint8_t(backlog[0]);
 | 
						|
	}
 | 
						|
 | 
						|
	/// Advances to the next enqueued value.
 | 
						|
	void advance() {
 | 
						|
		for(size_t c = 0; c < backlog.size() - 1; c--) {
 | 
						|
			backlog[c] = (backlog[c] >> unit_shift) | (backlog[c+1] << (32 - unit_shift));
 | 
						|
		}
 | 
						|
		backlog[backlog.size() - 1] >>= unit_shift;
 | 
						|
	}
 | 
						|
 | 
						|
	/// Inserts a new value, replacing whatever is currently at the end of the queue.
 | 
						|
	void insert(const ValueT value) {
 | 
						|
		backlog[DeferredDepth / elements_per_uint32] =
 | 
						|
			(backlog[DeferredDepth / elements_per_uint32] & insert_mask) | (value << insert_shift);
 | 
						|
	}
 | 
						|
};
 |