#Library design choice wifh SoA

1 messages · Page 1 of 1 (latest)

terse ore
#

Hi guys, I'm making a library with SoA types in it and I want to see your preference.

The codes look like this:

typedef struct FooArray {
    int a[LENGTH];
    int b[LENGTH]; // There are more than two member vars in my actual library. They are 6 of em.
    size_t len;
} FooArray;

typedef struct FooSomething {
    int a[SOME_LENGTH];
    int b[SOME_LENGTH];
    size_t len;
} FooSomething;

typedef struct FooVector {
    int *a;
    int *b;
    size_t len;
} FooVector;

void assign_value((FooArray or FooSomething or FooVector) *foo, int a, int b) {
    memset(foo->a, a, foo->len * sizeof(int));
    memset(foo->b, b, foo->len * sizeof(int));
}

The problem is assign_values. It basically does the same thing to different types. And it's likely to be called inside a loop. These are few options I've considered.

Option A:


typedef FooVector FooSpan; // It's a view like std::span in cpp.

FooSpan array_to_span(FooArray *foo);
FooSpan something_to_span(FooSomething *foo);
void assign_values(FooSpan foo, int a, int b) { ... }

...

FooArray arr;
assign_values(array_to_span(&arr), 0, 0);

Option B:

void priv_assign_values(int *a, int *b, size_t len, int i, int j) {
    memset(a, i, len * sizeof(int);
    memset(b, j, len * sizeof(int));
}
#define assign_values(foo, a, b) priv_assign_values(foo.a, foo.b, foo.len, a, b)

...

FooArray arr;
assign_values(arr, 0, 0);

Option C:

// Do the span things like in A
// Make private function like in B
void assign_values(FooSpan s, int a, int b) {
    priv_assign_values(s.a, s.b s.len, a, b);
}

...

// Same with A

What's your pick? Also give me other ideas too!
Thanks in advance.

quartz remnantBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

real jackal
#

why not use _Generic? consider:

#define assign(to, val) _Generic((to), \
   struct foo *: foo_assign, \
   struct bar *: bar_assign, \
   struct baz *: baz_assign  \
)((to), (val))

struct foo {
  int a;
};

struct bar {
  long a;
};

struct baz {
  double a;
};

void foo_assign(struct foo *foo, int a) {
  foo->a = a;
}

void bar_assign(struct bar *bar, long a) {
  bar->a = a;
}

void baz_assign(struct baz *baz, double a) {
  baz->a = a;
}

int main(void) {
  struct foo foo = ...;
  struct bar bar = ...;
  struct baz baz = ...;

  assign(&foo, 1);
  assign(&bar, 2U);
  assign(&baz, 3.);
}```
terse ore
#

!solved