Improve memory model of coral::stack
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									fb06ce217f
								
							
						
					
					
						commit
						f601f51f7a
					
				@ -2,9 +2,10 @@ export module coral.sequence;
 | 
			
		||||
 | 
			
		||||
import coral;
 | 
			
		||||
 | 
			
		||||
// Collections.
 | 
			
		||||
export namespace coral {
 | 
			
		||||
	/**
 | 
			
		||||
	 * Result codes used by [sequence]-derived types when they are appended to in any way.
 | 
			
		||||
	 * Result codes used by [contiguous_range]-derived types when they are appended to in any way.
 | 
			
		||||
	 *
 | 
			
		||||
	 * [append_result::ok] indicates that an append operation was successful.
 | 
			
		||||
	 *
 | 
			
		||||
@ -17,27 +18,36 @@ export namespace coral {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Base type for all sequence-like types.
 | 
			
		||||
	 * Base type for all collections which store their elements as a single block of contiguous
 | 
			
		||||
	 * memory.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Sequences are any data structure which owns a linear, non-unique set of elements which may
 | 
			
		||||
	 * be queried and/or mutated.
 | 
			
		||||
	 */
 | 
			
		||||
	template<typename element> struct sequence {
 | 
			
		||||
		virtual ~sequence() {};
 | 
			
		||||
	template<typename element> struct contiguous_range {
 | 
			
		||||
		virtual ~contiguous_range() {};
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Attempts to append `source_elements` to the sequence.
 | 
			
		||||
		 * Attempts to append `source_elements` to the contiguous_range.
 | 
			
		||||
		 *
 | 
			
		||||
		 * The returned [append_result] indicates whether the operation was successful or not.
 | 
			
		||||
		 *
 | 
			
		||||
		 * If the returned [append_result] is anything but [append_result::ok], the [sequence] will
 | 
			
		||||
		 * be left in an implementation-defined state.
 | 
			
		||||
		 * If the returned [append_result] is anything but [append_result::ok], the
 | 
			
		||||
		 * [contiguous_range] will be left in an implementation-defined state.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual append_result append(slice<element const> const & source_elements) = 0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns a read-only [slice] of the current range values.
 | 
			
		||||
		 *
 | 
			
		||||
		 * *Note*: the behavior of retaining the returned value past the scope of the source
 | 
			
		||||
		 * [contiguous_range] or any subsequent modifications to it is implementation-defined.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual slice<element const> as_slice() = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Last-in-first-out linear sequence of `element` values.
 | 
			
		||||
	 * Last-in-first-out contiguous range of `element` values.
 | 
			
		||||
	 *
 | 
			
		||||
	 * [stack] types will default to using an inline array of `init_capacity` at first. After all
 | 
			
		||||
	 * local storage has been exhausted, the [stack] will switch to a dynamic buffer. Because of
 | 
			
		||||
@ -48,7 +58,7 @@ export namespace coral {
 | 
			
		||||
	 * *Note*: the [allocator] referenced in the stack must remain valid for the duration of the
 | 
			
		||||
	 * stack lifetime.
 | 
			
		||||
	 */
 | 
			
		||||
	template<typename element, usize init_capacity = 1> struct stack : public sequence<element> {
 | 
			
		||||
	template<typename element, usize init_capacity = 1> struct stack : public contiguous_range<element> {
 | 
			
		||||
		stack(allocator * dynamic_allocator) {
 | 
			
		||||
			this->dynamic_allocator = dynamic_allocator;
 | 
			
		||||
		}
 | 
			
		||||
@ -88,6 +98,16 @@ export namespace coral {
 | 
			
		||||
			return append_result::ok;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns a read-only [slice] of the current stack values.
 | 
			
		||||
		 *
 | 
			
		||||
		 * *Note*: the returned slice should be considered invalid if any mutable operation is
 | 
			
		||||
		 * performed on the source [stack] or it is no longer in scope.
 | 
			
		||||
		 */
 | 
			
		||||
		slice<element const> as_slice() override {
 | 
			
		||||
			return this->elements.sliced(0, this->filled);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns `true` if the stack is backed by dynamic memory, otherwise `false`.
 | 
			
		||||
		 */
 | 
			
		||||
@ -172,17 +192,22 @@ export namespace coral {
 | 
			
		||||
 | 
			
		||||
		u8 local_buffer[init_capacity]{0};
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using contiguous_byte_range = coral::contiguous_range<coral::u8>;
 | 
			
		||||
 | 
			
		||||
// Reader / writers.
 | 
			
		||||
export namespace coral {
 | 
			
		||||
	/**
 | 
			
		||||
	 * Writable type for appending data to a [sequence] containing [u8] values.
 | 
			
		||||
	 * Readable type for streaming data from a [contiguous_range] containing [u8] values.
 | 
			
		||||
	 */
 | 
			
		||||
	struct sequence_writer : public writer {
 | 
			
		||||
		sequence_writer(sequence<u8> * output_sequence) {
 | 
			
		||||
			this->output_sequence = output_sequence;
 | 
			
		||||
	struct contiguous_reader : public reader {
 | 
			
		||||
		contiguous_reader(contiguous_byte_range * range) {
 | 
			
		||||
			this->range = range;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		expected<usize, io_error> write(slice<u8 const> const & buffer) {
 | 
			
		||||
			switch (output_sequence->append(buffer)) {
 | 
			
		||||
			switch (this->range->append(buffer)) {
 | 
			
		||||
				case append_result::ok: return buffer.length;
 | 
			
		||||
				case append_result::out_of_memory: return io_error::unavailable;
 | 
			
		||||
				default: unreachable();
 | 
			
		||||
@ -190,6 +215,26 @@ export namespace coral {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
		sequence<u8> * output_sequence;
 | 
			
		||||
		contiguous_byte_range * range;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Writable type for appending data to a [contiguous_range] containing [u8] values.
 | 
			
		||||
	 */
 | 
			
		||||
	struct contiguous_writer : public writer {
 | 
			
		||||
		contiguous_writer(contiguous_byte_range * range) {
 | 
			
		||||
			this->range = range;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		expected<usize, io_error> write(slice<u8 const> const & buffer) {
 | 
			
		||||
			switch (this->range->append(buffer)) {
 | 
			
		||||
				case append_result::ok: return buffer.length;
 | 
			
		||||
				case append_result::out_of_memory: return io_error::unavailable;
 | 
			
		||||
				default: unreachable();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
		contiguous_byte_range * range;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,12 +32,12 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
			coral::stack<coral::u8> script_source{allocator};
 | 
			
		||||
			{
 | 
			
		||||
				coral::u8 stream_buffer[1024]{0};
 | 
			
		||||
				coral::sequence_writer script_writer{&script_source};
 | 
			
		||||
				coral::contiguous_writer script_writer{&script_source};
 | 
			
		||||
 | 
			
		||||
				if (!coral::stream(script_writer, file, stream_buffer).is_ok()) return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			vm.with_object(vm.compile(coral::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) {
 | 
			
		||||
			vm.with_object(vm.compile(script_source.as_slice().as_chars()), [&](kym::bound_object & script) {
 | 
			
		||||
				vm.with_object(script.call({}), [&](kym::bound_object & config) {
 | 
			
		||||
					constexpr auto as_u16 = [](coral::i64 value) -> coral::optional<coral::i16> {
 | 
			
		||||
						if ((value >= 0) && (value <= coral::u16_max))
 | 
			
		||||
@ -72,7 +72,7 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
		if (!is_config_loaded) {
 | 
			
		||||
			coral::stack<coral::u8> error_message{&system.thread_safe_allocator()};
 | 
			
		||||
			{
 | 
			
		||||
				coral::sequence_writer error_writer{&error_message};
 | 
			
		||||
				coral::contiguous_writer error_writer{&error_message};
 | 
			
		||||
 | 
			
		||||
				if (!error_writer.write(coral::slice{"failed to load "}.as_bytes()).is_ok())
 | 
			
		||||
					return coral::u8_max;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user