From 05630cf10cc01a237131989248261149f03fc8ab Mon Sep 17 00:00:00 2001
From: Mitya Selivanov <0x7fffff@guattari.ru>
Date: Sun, 7 Aug 2022 08:55:32 +0400
Subject: static array wrap, static string wrap

---
 CMakeLists.txt                          |  2 +-
 source/kit/array_ref.h                  | 16 ++++++++++++++++
 source/kit/string_ref.h                 |  8 ++++++++
 source/test/unittests/CMakeLists.txt    |  6 +++---
 source/test/unittests/array_ref.test.c  | 23 +++++++++++++++++++++++
 source/test/unittests/string_ref.test.c | 17 +++++++++++++++++
 6 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 source/test/unittests/string_ref.test.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5fe8e4..01fbba9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,7 +20,7 @@ endif()
 project(
   ${KIT_PROJECT}
   VERSION 0.1.1
-  DESCRIPTION "Kit"
+  DESCRIPTION "A collection of C libraries"
   LANGUAGES C)
 
 if(KIT_ENABLE_LIBRARY OR KIT_ENABLE_TESTING)
diff --git a/source/kit/array_ref.h b/source/kit/array_ref.h
index b43db04..f34927c 100644
--- a/source/kit/array_ref.h
+++ b/source/kit/array_ref.h
@@ -31,6 +31,20 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size,
     type_ const *values;           \
   } name_
 
+#define KIT_AR_WRAP(name_, array_)                              \
+  struct {                                                      \
+    ptrdiff_t            size;                                  \
+    typeof((array_)[0]) *values;                                \
+  } name_ = { .size   = (sizeof(array_) / sizeof((array_)[0])), \
+              .values = (array_) }
+
+#define KIT_AR_CONST_WRAP(name_, array_)                        \
+  struct {                                                      \
+    ptrdiff_t                  size;                            \
+    typeof((array_)[0]) const *values;                          \
+  } name_ = { .size   = (sizeof(array_) / sizeof((array_)[0])), \
+              .values = (array_) }
+
 #define KIT_AR_TYPE(name_, element_type_) \
   typedef struct {                        \
     ptrdiff_t      size;                  \
@@ -61,6 +75,8 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size,
 
 #  define AR KIT_AR
 #  define AR_CONST KIT_AR_CONST
+#  define AR_WRAP KIT_AR_WRAP
+#  define AR_CONST_WRAP KIT_AR_CONST_WRAP
 #  define AR_TYPE KIT_AR_TYPE
 #  define AR_TYPE_CONST KIT_AR_TYPE_CONST
 #  define AR_EQUAL KIT_AR_EQUAL
diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h
index 79a023b..8832e51 100644
--- a/source/kit/string_ref.h
+++ b/source/kit/string_ref.h
@@ -13,11 +13,19 @@ KIT_AR_TYPE_CONST(kit_string_cref_t, char);
 typedef kit_string_ref_t  kit_out_str_t;
 typedef kit_string_cref_t kit_cstr_t;
 
+#define KIT_SZ(name_, static_str_)                                  \
+  KIT_AR_CONST(name_, typeof((static_str_)[0])) = {                 \
+    .size   = (sizeof(static_str_) / sizeof((static_str_)[0])) - 1, \
+    .values = (static_str_)                                         \
+  }
+
 #ifndef KIT_DISABLE_SHORT_NAMES
 #  define string_ref_t kit_string_ref_t
 #  define string_cref_t kit_string_cref_t
 #  define out_str_t kit_out_str_t
 #  define cstr_t kit_cstr_t
+
+#  define SZ KIT_SZ
 #endif
 
 #ifdef __cplusplus
diff --git a/source/test/unittests/CMakeLists.txt b/source/test/unittests/CMakeLists.txt
index 75b1f3f..37f7dbb 100644
--- a/source/test/unittests/CMakeLists.txt
+++ b/source/test/unittests/CMakeLists.txt
@@ -1,6 +1,6 @@
 target_sources(
   ${KIT_TEST_SUITE}
     PRIVATE
-      async_function.test.c main.test.c array_ref.test.c
-      input_stream.test.c lower_bound.test.c input_buffer.test.c
-      dynamic_array.test.c)
+      async_function.test.c main.test.c string_ref.test.c
+      array_ref.test.c input_stream.test.c lower_bound.test.c
+      input_buffer.test.c dynamic_array.test.c)
diff --git a/source/test/unittests/array_ref.test.c b/source/test/unittests/array_ref.test.c
index d8cbcec..27b754b 100644
--- a/source/test/unittests/array_ref.test.c
+++ b/source/test/unittests/array_ref.test.c
@@ -3,6 +3,29 @@
 #define KIT_TEST_FILE array_ref
 #include "../../kit_test/test.h"
 
+TEST("array ref const wrap") {
+  int foo[] = { 1, 2, 3 };
+  AR_CONST_WRAP(ref, foo);
+
+  REQUIRE(ref.size == 3);
+  REQUIRE(ref.values[0] == 1);
+  REQUIRE(ref.values[1] == 2);
+  REQUIRE(ref.values[2] == 3);
+}
+
+TEST("array ref wrap") {
+  int foo[] = { 1, 2, 3 };
+  AR_WRAP(ref, foo);
+
+  REQUIRE(ref.size == 3);
+  REQUIRE(ref.values[0] == 1);
+  REQUIRE(ref.values[1] == 2);
+  REQUIRE(ref.values[2] == 3);
+
+  ref.values[1] = 42;
+  REQUIRE(ref.values[1] == 42);
+}
+
 TEST("array ref equal") {
   int foo[] = { 1, 2, 3, 4, 5, 6, 7 };
   int bar[] = { 3, 4, 5 };
diff --git a/source/test/unittests/string_ref.test.c b/source/test/unittests/string_ref.test.c
new file mode 100644
index 0000000..b89459e
--- /dev/null
+++ b/source/test/unittests/string_ref.test.c
@@ -0,0 +1,17 @@
+#include "../../kit/string_ref.h"
+
+#define KIT_TEST_FILE string_ref
+#include "../../kit_test/test.h"
+
+TEST("static string wrap") {
+  SZ(ref, "foo bar");
+
+  REQUIRE(ref.size == 7);
+  REQUIRE(ref.values[0] == 'f');
+  REQUIRE(ref.values[1] == 'o');
+  REQUIRE(ref.values[2] == 'o');
+  REQUIRE(ref.values[3] == ' ');
+  REQUIRE(ref.values[4] == 'b');
+  REQUIRE(ref.values[5] == 'a');
+  REQUIRE(ref.values[6] == 'r');
+}
-- 
cgit v1.2.3