Use Box for Wrapper implementation

This won't raise on invalid casts.
It should reduce the amount of instantiated types and methods.
This commit is contained in:
Michael Miller 2022-03-19 22:48:55 -06:00
parent 18a03b02fe
commit e209fe3eb5
No known key found for this signature in database
GPG key ID: 32B47AE8F388A1FF
2 changed files with 4 additions and 32 deletions

View file

@ -10,9 +10,4 @@ Spectator.describe Spectator::Wrapper do
wrapper = described_class.new(Int32) wrapper = described_class.new(Int32)
expect(wrapper.get { Int32 }).to eq(Int32) expect(wrapper.get { Int32 }).to eq(Int32)
end end
it "raises on invalid cast" do
wrapper = described_class.new(42)
expect { wrapper.get(String) }.to raise_error(TypeCastError)
end
end end

View file

@ -9,18 +9,17 @@ module Spectator
# value = wrapper.get(String) # value = wrapper.get(String)
# ``` # ```
struct Wrapper struct Wrapper
@value : TypelessValue @pointer : Void*
# Creates a wrapper for the specified value. # Creates a wrapper for the specified value.
def initialize(value) def initialize(value)
@value = Value.new(value) @pointer = Box.box(value)
end end
# Retrieves the previously wrapped value. # Retrieves the previously wrapped value.
# The *type* of the wrapped value must match otherwise an error will be raised. # The *type* of the wrapped value must match otherwise an error will be raised.
def get(type : T.class) : T forall T def get(type : T.class) : T forall T
value = @value.as(Value(T)) Box(T).unbox(@pointer)
value.get
end end
# Retrieves the previously wrapped value. # Retrieves the previously wrapped value.
@ -35,29 +34,7 @@ module Spectator
# type = wrapper.get { Int32 } # Returns Int32 # type = wrapper.get { Int32 } # Returns Int32
# ``` # ```
def get(& : -> T) : T forall T def get(& : -> T) : T forall T
value = @value.as(Value(T)) Box(T).unbox(@pointer)
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
end end
end end
end end