diff --git a/SPEC.md b/SPEC.md index e0a6ee9..63ba982 100644 --- a/SPEC.md +++ b/SPEC.md @@ -552,6 +552,39 @@ class Point end ``` +### §2.6 Generic types + +Only sequential container types are instantiated on the Crystal side, as if each +container implements the following interface: + +```crystal +module Container(T) + include Indexable(T) + + # All containers must be default-constructible + # abstract def initialize + + abstract def unsafe_fetch(index : Int) : T + abstract def push(value : T) : Void + abstract def size : Int32 + + def <<(x : T) + push(x) + self + end + + def concat(values : Enumerable(T)) + values.each { |v| self << v } + self + end +end +``` + +Bindgen automatically collects all instantiations of each container type that +appear in method argument types or return types; explicit instantiations may be +configured with the `containers` section. Aliases to complete container types +and container type arguments are both supported. + ## §3. Crystal bindings ### §3.1 Naming scheme diff --git a/spec/integration/containers.cpp b/spec/integration/containers.cpp index 73ae0f5..db9cd2a 100644 --- a/spec/integration/containers.cpp +++ b/spec/integration/containers.cpp @@ -1,6 +1,9 @@ #include #include +typedef std::vector bytearray; +typedef unsigned int rgb; + class Containers { public: std::vector integers() { @@ -15,6 +18,14 @@ class Containers { return std::vector{ "One", "Two", "Three" }; } + bytearray chars() { + return { 0x01, 0x04, 0x09 }; + } + + std::vector palette() { + return { 0xFF0000, 0x00FF00, 0x0000FF }; + } + double sum(std::vector list) { double d = 0; diff --git a/spec/integration/containers.yml b/spec/integration/containers.yml index 6479a5c..48256ff 100644 --- a/spec/integration/containers.yml +++ b/spec/integration/containers.yml @@ -2,6 +2,7 @@ processors: - filter_methods + - auto_container_instantiation - instantiate_containers - default_constructor - cpp_wrapper @@ -17,6 +18,8 @@ containers: type: Sequential instantiations: - [ "int" ] - - [ "double" ] - - [ "std::string" ] - [ "std::vector" ] + +types: + rgb: { alias_for: "unsigned int" } + bytearray: { alias_for: std::vector } diff --git a/spec/integration/containers_spec.cr b/spec/integration/containers_spec.cr index b7ae929..7dbbfb6 100644 --- a/spec/integration/containers_spec.cr +++ b/spec/integration/containers_spec.cr @@ -17,6 +17,14 @@ describe "container instantiation feature" do Test::Containers.new.sum(list).should eq(4.0) end + it "works with auto instantiated container (aliased container)" do + Test::Containers.new.chars.to_a.should eq([1u8, 4u8, 9u8]) + end + + it "works with auto instantiated container (aliased element)" do + Test::Containers.new.palette.to_a.should eq([0xFF0000u32, 0x00FF00u32, 0x0000FFu32]) + end + it "works with nested containers" do Test::Containers.new.grid.to_a.map(&.to_a).should eq([[1, 4], [9, 16]]) end