From 419e7c1b8dcdd9a0a01a004b89a0131676c6ba17 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sat, 19 Mar 2022 22:48:55 -0600 Subject: [PATCH] Use Box for Wrapper implementation This won't raise on invalid casts. It should reduce the amount of instantiated types and methods. --- spec/spectator/wrapper_spec.cr | 5 ----- src/spectator/wrapper.cr | 31 ++++--------------------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/spec/spectator/wrapper_spec.cr b/spec/spectator/wrapper_spec.cr index aa2351c..9920adc 100644 --- a/spec/spectator/wrapper_spec.cr +++ b/spec/spectator/wrapper_spec.cr @@ -10,9 +10,4 @@ Spectator.describe Spectator::Wrapper do wrapper = described_class.new(Int32) expect(wrapper.get { Int32 }).to eq(Int32) end - - it "raises on invalid cast" do - wrapper = described_class.new(42) - expect { wrapper.get(String) }.to raise_error(TypeCastError) - end end diff --git a/src/spectator/wrapper.cr b/src/spectator/wrapper.cr index 21bd0ec..5c79910 100644 --- a/src/spectator/wrapper.cr +++ b/src/spectator/wrapper.cr @@ -9,18 +9,17 @@ module Spectator # value = wrapper.get(String) # ``` struct Wrapper - @value : TypelessValue + @pointer : Void* # Creates a wrapper for the specified value. def initialize(value) - @value = Value.new(value) + @pointer = Box.box(value) end # Retrieves the previously wrapped value. # The *type* of the wrapped value must match otherwise an error will be raised. def get(type : T.class) : T forall T - value = @value.as(Value(T)) - value.get + Box(T).unbox(@pointer) end # Retrieves the previously wrapped value. @@ -35,29 +34,7 @@ module Spectator # type = wrapper.get { Int32 } # Returns Int32 # ``` def get(& : -> T) : T forall T - value = @value.as(Value(T)) - value.get - end - - # Base type that generic types inherit from. - # This provides a common base type, - # since Crystal doesn't support storing an `Object` (yet). - # Instances of this type must be downcast to `Value` to be useful. - private abstract class TypelessValue - end - - # Generic value wrapper. - # Simply holds a value and inherits from `TypelessValue`, - # so that all types of this class can be stored as one. - private class Value(T) < TypelessValue - # Creates the wrapper with the specified value. - def initialize(@value : T) - end - - # Retrieves the wrapped value. - def get : T - @value - end + Box(T).unbox(@pointer) end end end