blob: ba006302e0cf8949973fd8179f2f00d293cb4a5a [file]
// A function that passes arrays by reference
%module arrayref
%{
#include <string.h>
%}
%inline %{
void foo(const int (&x)[10]) {
}
void bar(int (&x)[10]) {
}
int numbers[4] = {1, 2, 3, 4};
int others[4] = {10, 20, 30, 40};
// A variable that is a reference to an array is set by copying the elements of the array it refers
// to, as the array itself is, rather than by an array assignment, which does not compile.
int (&numbers_ref)[4] = numbers;
// A language that wraps an array of char as a string wraps a reference to one the same way.
char letters[4] = "abc";
char (&letters_ref)[4] = letters;
// A reference to an array of const cannot be written through, so the variable is read only, in the
// same way the array it refers to is.
const char frozen[4] = "xyz";
const char (&frozen_ref)[4] = frozen;
int (*others_address())[4] { return &others; }
int numbers_sum() {
return numbers[0] + numbers[1] + numbers[2] + numbers[3];
}
const char *letters_are() { return letters; }
// An argument that is a reference to an array of char is a string too, but never null, as a reference cannot be.
int length_of(const char (&text)[8]) { return (int)strlen(text); }
int length_of_writable(char (&text)[8]) { return (int)strlen(text); }
// A string selects an overload taking a reference to an array of char.
struct ArrayRefOther {};
int char_ref_overload(ArrayRefOther) { return -1; }
int char_ref_overload(const char (&text)[8]) { return (int)strlen(text); }
struct ArrayRefMember {
int backing[4];
int (&member_ref)[4];
char text[8];
char (&text_ref)[8];
ArrayRefMember() : member_ref(backing), text_ref(text) {
for (int i = 0; i < 4; i++)
backing[i] = i + 1;
strcpy(text, "hi");
}
int sum() const {
return backing[0] + backing[1] + backing[2] + backing[3];
}
const char *text_is() const { return text; }
};
// Setting a reference to an array of arrays copies every element, not only the first of each row.
typedef int Row[3];
int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
int other_grid[2][3] = {{10, 20, 30}, {40, 50, 60}};
int (&grid_ref)[2][3] = grid;
int (*other_grid_address())[2][3] { return &other_grid; }
int grid_element(int i, int j) { return grid[i][j]; }
struct GridRefMember {
int backing[2][3];
Row (&rows_ref)[2];
GridRefMember() : rows_ref(backing) {
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
backing[i][j] = 0;
}
int element(int i, int j) const { return backing[i][j]; }
};
%}
// Setting a reference to an array of pointers, which only a template can declare, copies the pointers.
%inline %{
template<typename T> struct RefArrayHolder {
T backing[2];
T (&elements_ref)[2];
RefArrayHolder() : elements_ref(backing) {
backing[0] = 0;
backing[1] = 0;
}
};
int *pointers[2] = {&numbers[0], &numbers[3]};
int *(*pointers_address())[2] { return &pointers; }
bool holds_pointers(const RefArrayHolder<int *> &holder) {
return holder.backing[0] == pointers[0] && holder.backing[1] == pointers[1];
}
%}
%template(PointerRefArrayHolder) RefArrayHolder<int *>;