A code example would speak best to what I’m trying to achieve:
Crystal 1.3.0 (2022-01-06)
struct Matrix(T, W, H)
{% begin %}
property values : StaticArray(T, {{W * H}})
{% end %}
def initialize
@values = StaticArray(T, {{ W * H }}).new(T.new(0))
end
end
Is there a way to specify (through macros, or otherwise?) that the StaticArray
type is W * H
in size somehow?
I could use values : Slice(T)
or values : Pointer(T)
but in benchmarking the allocation and multiplication of various collection types in this struct, my results showed StaticArray to be faster than pointers:
user system total real
pointer 0.243436 0.235193 0.478629 ( 0.254651)
slice 0.234756 0.220551 0.455307 ( 0.244790)
static array 0.117237 0.151175 0.268412 ( 0.124297)
tuple 0.116266 0.147461 0.263727 ( 0.122882)
vars 0.118009 0.153231 0.271240 ( 0.125376)
I’ve tried using the TypeNode#type_vars
macro method, but that seems to return a literal W * H
in this usage, which isn’t valid.
However, using this same approach in methods returns what I’d expect:
struct Matrix(T, W, H)
def self.size
{{ @type.type_vars[1] * @type.type_vars[2] }}
end
def size
{{ @type.type_vars[1] * @type.type_vars[2] }}
end
end
Matrix(Int32, 3, 3).size # => 9
Matrix(Int32, 3, 3).new.size # => 9
Appreciate any help/insight, thank you!