From 8d3c8eec30dbd5527ccab9fceb5dbf264c8cf1e1 Mon Sep 17 00:00:00 2001
From: Xiangze Li <lee_johnson@qq.com>
Date: Tue, 14 Jan 2025 09:52:48 +0800
Subject: [PATCH 1/3] =?UTF-8?q?feat(CppABI):=20STL=E7=B1=BB=E5=9E=8B?=
 =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A=E6=9E=84=E9=80=A0=E5=87=BD?=
 =?UTF-8?q?=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/cpp/stl/std_map.py             |  7 +++++++
 src/cpp/stl/std_pair.py            |  6 ++++++
 src/cpp/stl/std_vector.py          |  8 ++++++++
 test/catch2/cpp/catch2_cpp_stl.cpp | 16 +++++++++-------
 4 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/cpp/stl/std_map.py b/src/cpp/stl/std_map.py
index c6067acf..1e065318 100644
--- a/src/cpp/stl/std_map.py
+++ b/src/cpp/stl/std_map.py
@@ -122,6 +122,7 @@ public:
     return self_;
   }}
 
+  {stl_type_name}(const std::initializer_list<std::pair<const {key_type_name}, {value_type_name}>> list);
   {stl_type_name}(const std::map<{key_type_name}, {value_type_name}> &other);
   operator std::map<{key_type_name}, {value_type_name}>() const;
   std::map<{key_type_name}, {value_type_name}> to_std() const;
@@ -165,6 +166,12 @@ inline void {stl_type_name}::erase(const {key_type_name} & key) {{
   {c_stl_type_name}_erase(self_, {key_cpp_to_c});
 }}
 
+inline {stl_type_name}::{stl_type_name}(const std::initializer_list<std::pair<const {key_type_name}, {value_type_name}>> list) {{
+  self_ = new_{c_stl_type_name}();
+  for (const auto &[key, value] : list) {{
+    this->insert(key, value);
+  }}
+}}
 inline {stl_type_name}::{stl_type_name}(const std::map<{key_type_name}, {value_type_name}> &other) {{
   self_ = new_{c_stl_type_name}();
   for (const auto &[key, value] : other) {{
diff --git a/src/cpp/stl/std_pair.py b/src/cpp/stl/std_pair.py
index 0180c69f..f85a5b60 100644
--- a/src/cpp/stl/std_pair.py
+++ b/src/cpp/stl/std_pair.py
@@ -5,6 +5,7 @@ function_def = """  {first_type_name} get_first() const;
   void set_first(const {first_type_name} & value);
   void set_second(const {second_type_name} & value);
 
+  {stl_type_name}(const {first_type_name} & first, const {second_type_name} & second);
   operator std::pair<{first_type_name}, {second_type_name}>() const;
   std::pair<{first_type_name}, {second_type_name}> to_std() const;"""
 
@@ -28,6 +29,11 @@ inline void {stl_class_name}::set_second(const {{second_type_name}} & second) {{
   {{c_stl_type_name}}_set_second({self}, {{second_cpp_to_c}});
 }}}}
 
+inline {stl_class_name}::{stl_class_name}(const {{first_type_name}} & first, const {{second_type_name}} & second) {{{{
+  self_ = new_{{c_stl_type_name}}();
+  this->set_first(first);
+  this->set_second(second);
+}}}}
 inline {stl_class_name}::operator std::pair<{{first_type_name}}, {{second_type_name}}>() const {{{{
   return std::pair<{{first_type_name}}, {{second_type_name}}>(this->get_first(), this->get_second());
 }}}}
diff --git a/src/cpp/stl/std_vector.py b/src/cpp/stl/std_vector.py
index 7fd0896e..75f88a4a 100644
--- a/src/cpp/stl/std_vector.py
+++ b/src/cpp/stl/std_vector.py
@@ -11,6 +11,7 @@ function_def = """  bool empty() const;
   void clear();
   void erase(unsigned long long index);
 
+  {stl_type_name}(std::initializer_list<{value_type_name}> list);
   {stl_type_name}(const std::vector<{value_type_name}> & other);
   operator std::vector<{value_type_name}>() const;
   std::vector<{value_type_name}> to_std() const;"""
@@ -48,6 +49,13 @@ inline void {stl_class_name}::erase(unsigned long long index) {{{{
   {{c_stl_type_name}}_erase({self}, index);
 }}}}
 
+inline {stl_class_name}::{stl_class_name}(std::initializer_list<{{value_type_name}}> list) {{{{
+  self_ = new_{{c_stl_type_name}}();
+  this->reserve(list.size());
+  for (const auto &item : list) {{{{
+    this->push_back(item);
+  }}}}
+}}}}
 inline {stl_class_name}::{stl_class_name}(const std::vector<{{value_type_name}}> &other) {{{{
   self_ = new_{{c_stl_type_name}}();
   this->reserve(other.size());
diff --git a/test/catch2/cpp/catch2_cpp_stl.cpp b/test/catch2/cpp/catch2_cpp_stl.cpp
index 741fa083..7b91334e 100644
--- a/test/catch2/cpp/catch2_cpp_stl.cpp
+++ b/test/catch2/cpp/catch2_cpp_stl.cpp
@@ -73,7 +73,7 @@ TEST_CASE("Test cpp auto bind stl", "[bind][cpp][stl]") {
   {
     INFO("Test cpp auto bind map convertion with std::map");
 
-    cpp2x::MapIntFloat cpp2x_map = std::map<int, float>{{1, 2.0f}, {3, 4.0f}};
+    cpp2x::MapIntFloat cpp2x_map{{1, 2.0f}, {3, 4.0f}};
     CHECK(cpp2x_map.size() == 2);
     CHECK(cpp2x_map.at(1) == 2.0f);
     CHECK(cpp2x_map.at(3) == 4.0f);
@@ -108,6 +108,9 @@ TEST_CASE("Test cpp auto bind stl", "[bind][cpp][stl]") {
     cpp2x::PairIntFloat pair2 = std::make_pair(1, 2.0f);
     CHECK(pair2.get_first() == 1);
     CHECK(pair2.get_second() == 2.0f);
+
+    cpp2x::PairIntFloat pair3{1, 2.};
+    CHECK(pair3.to_std() == pair2.to_std());
   }
 
   {
@@ -130,7 +133,7 @@ TEST_CASE("Test cpp auto bind stl", "[bind][cpp][stl]") {
   {
     INFO("Test cpp auto bind vector");
 
-    cpp2x::VectorInt cpp2x_vec_int = std::vector<int>{1, 2, 3, 4};
+    cpp2x::VectorInt cpp2x_vec_int{1, 2, 3, 4};
     CHECK(cpp2x_vec_int.size() == 4);
     CHECK(cpp2x_vec_int.get(0) == 1);
     CHECK(cpp2x_vec_int.get(1) == 2);
@@ -145,11 +148,10 @@ TEST_CASE("Test cpp auto bind stl", "[bind][cpp][stl]") {
     CHECK(cpp2x_vec_str.get(2) == "3");
     CHECK(cpp2x_vec_str.get(3) == "4");
 
-    cpp2x::VectorVectorString cpp2x_vec_vec_str =
-        std::vector<cpp2x::VectorString>{
-            cpp2x::VectorString({"1", "2", "3"}),
-            cpp2x::VectorString({"4", "5", "6"}),
-        };
+    cpp2x::VectorVectorString cpp2x_vec_vec_str{
+        {"1", "2", "3"},
+        {"4", "5", "6"},
+    };
     CHECK(cpp2x_vec_vec_str.size() == 2);
     CHECK(cpp2x_vec_vec_str.get(0).to_std() ==
           std::vector<cpp2x::String>{"1", "2", "3"});
-- 
GitLab


From 8fefc5ae0e442bdd7bd2cbf482c6357666dee9a4 Mon Sep 17 00:00:00 2001
From: Xiangze Li <lee_johnson@qq.com>
Date: Tue, 14 Jan 2025 09:52:48 +0800
Subject: [PATCH 2/3] =?UTF-8?q?feat(CppABI):=20STL=E7=B1=BB=E5=9E=8B?=
 =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A=E6=9E=84=E9=80=A0=E5=87=BD?=
 =?UTF-8?q?=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/c/stl/std_pair.py                            | 16 ++++++++++++----
 src/c/stl/translators.py                         |  4 ++--
 src/c/stl/utils.py                               |  8 ++++----
 src/cpp/stl/std_pair.py                          |  4 +---
 test/catch2/c/catch2_c_stl.cpp                   | 12 ++++++++++++
 .../pytest_c_translators_stl_std_pair.py         | 15 +++++++++++----
 6 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/src/c/stl/std_pair.py b/src/c/stl/std_pair.py
index 89ad75a0..74d69149 100644
--- a/src/c/stl/std_pair.py
+++ b/src/c/stl/std_pair.py
@@ -27,6 +27,7 @@ extern "C" {{
 #endif // __cplusplus
 
 {default_ctor}
+{abi_macro}{c_pair_type_name} new_{c_pair_type_name}_field({c_first_type_name} first, {c_second_type_name} second);
 {abi_macro}void delete_{c_pair_type_name}({c_pair_type_name} c_pair);
 {abi_macro}{c_pair_type_name} copy_{c_pair_type_name}(const {c_pair_type_name}* c_pair);
 {abi_macro}{c_pair_type_name} move_{c_pair_type_name}({c_pair_type_name}* c_pair);
@@ -35,8 +36,8 @@ extern "C" {{
 
 {abi_macro}{c_first_type_name} {c_pair_type_name}_get_first({c_pair_type_name} c_pair);
 {abi_macro}{c_second_type_name} {c_pair_type_name}_get_second({c_pair_type_name} c_pair);
-{abi_macro}void {c_pair_type_name}_set_first({c_pair_type_name} c_pair, {c_first_type_name} value);
-{abi_macro}void {c_pair_type_name}_set_second({c_pair_type_name} c_pair, {c_second_type_name} value);
+{abi_macro}void {c_pair_type_name}_set_first({c_pair_type_name} c_pair, {c_first_type_name} first);
+{abi_macro}void {c_pair_type_name}_set_second({c_pair_type_name} c_pair, {c_second_type_name} second);
 
 #ifdef __cplusplus
 }}
@@ -56,6 +57,13 @@ cpp_tpl: str = """#include <utility>
 
 {default_ctor}
 
+{c_pair_type_name} new_{c_pair_type_name}_field({c_first_type_name} first, {c_second_type_name} second) {{
+  return {{
+    new std::pair<{first_type_name}, {second_type_name}>({c_first_to_cpp}, {c_second_to_cpp}),
+    true
+  }};
+}}
+
 void delete_{c_pair_type_name}({c_pair_type_name} c_pair) {{
   if (c_pair.mem_owner) {{
     delete reinterpret_cast<std::pair<{first_type_name}, {second_type_name}> *>(c_pair.ptr);
@@ -98,11 +106,11 @@ void delete_{c_pair_type_name}({c_pair_type_name} c_pair) {{
   return {cpp_second_to_c};
 }}
 
-void {c_pair_type_name}_set_first({c_pair_type_name} c_pair, {c_first_type_name} value) {{
+void {c_pair_type_name}_set_first({c_pair_type_name} c_pair, {c_first_type_name} first) {{
   reinterpret_cast<std::pair<{first_type_name}, {second_type_name}> *>(c_pair.ptr)->first = {c_first_to_cpp};
 }}
 
-void {c_pair_type_name}_set_second({c_pair_type_name} c_pair, {c_second_type_name} value) {{
+void {c_pair_type_name}_set_second({c_pair_type_name} c_pair, {c_second_type_name} second) {{
   reinterpret_cast<std::pair<{first_type_name}, {second_type_name}> *>(c_pair.ptr)->second = {c_second_to_cpp};
 }}
 """
diff --git a/src/c/stl/translators.py b/src/c/stl/translators.py
index 06348a64..14844490 100644
--- a/src/c/stl/translators.py
+++ b/src/c/stl/translators.py
@@ -491,8 +491,8 @@ class CDefaultStdPairTranslator(common_translators.DefaultStdPairTranslator):
             second_type_name=second_type_name,
             cpp_first_to_c=utils.value_to_c(first_type),
             cpp_second_to_c=utils.value_to_c(second_type),
-            c_first_to_cpp=utils.value_to_cpp(first_type),
-            c_second_to_cpp=utils.value_to_cpp(second_type),
+            c_first_to_cpp=utils.value_to_cpp(first_type, "first"),
+            c_second_to_cpp=utils.value_to_cpp(second_type, "second"),
             default_ctor=(
                 std_pair.cpp_default_ctor_tpl.format(
                     c_pair_type_name=c_pair_type_name,
diff --git a/src/c/stl/utils.py b/src/c/stl/utils.py
index aaaa1983..77f5c414 100644
--- a/src/c/stl/utils.py
+++ b/src/c/stl/utils.py
@@ -170,14 +170,14 @@ def value_to_c(value_type: cursors.DataType) -> str:
         return f"{{ new {value_type_name}(value), true }}"
 
 
-def value_to_cpp(value_type: cursors.DataType) -> str:
+def value_to_cpp(value_type: cursors.DataType, value_name="value") -> str:
     value_type_name: str = value_type.full_type_name
     if common_utils.is_c_base_type(value_type.canonical.base_type_name):
-        return "value"
+        return value_name
     elif value_type.get_declaration.is_enum:
-        return common_utils.enum_to_cpp(value_type)
+        return common_utils.enum_to_cpp(value_type, value_name)
     else:
-        return f"*reinterpret_cast<{value_type_name} *>(value.ptr)"
+        return f"*reinterpret_cast<{value_type_name} *>({value_name}.ptr)"
 
 
 def key_to_cpp(value_type: cursors.DataType) -> str:
diff --git a/src/cpp/stl/std_pair.py b/src/cpp/stl/std_pair.py
index f85a5b60..e2f83261 100644
--- a/src/cpp/stl/std_pair.py
+++ b/src/cpp/stl/std_pair.py
@@ -30,9 +30,7 @@ inline void {stl_class_name}::set_second(const {{second_type_name}} & second) {{
 }}}}
 
 inline {stl_class_name}::{stl_class_name}(const {{first_type_name}} & first, const {{second_type_name}} & second) {{{{
-  self_ = new_{{c_stl_type_name}}();
-  this->set_first(first);
-  this->set_second(second);
+  self_ = new_{{c_stl_type_name}}_field({{first_cpp_to_c}}, {{second_cpp_to_c}});
 }}}}
 inline {stl_class_name}::operator std::pair<{{first_type_name}}, {{second_type_name}}>() const {{{{
   return std::pair<{{first_type_name}}, {{second_type_name}}>(this->get_first(), this->get_second());
diff --git a/test/catch2/c/catch2_c_stl.cpp b/test/catch2/c/catch2_c_stl.cpp
index a00a966f..33756098 100644
--- a/test/catch2/c/catch2_c_stl.cpp
+++ b/test/catch2/c/catch2_c_stl.cpp
@@ -7,6 +7,18 @@
 
 #include "catch2/catch_test_macros.hpp"
 
+TEST_CASE("Test c auto bind stl pair", "[bind][c][stl][pair]") {
+  const auto pair = new_PairIntFloat_field(1, 1.0f);
+  CHECK(PairIntFloat_get_first(pair) == 1);
+  CHECK(PairIntFloat_get_second(pair) == 1.0f);
+  CHECK_NOTHROW(PairIntFloat_set_first(pair, 2));
+  CHECK(PairIntFloat_get_first(pair) == 2);
+  CHECK_NOTHROW(PairIntFloat_set_second(pair, 2.0f));
+  CHECK(PairIntFloat_get_second(pair) == 2.0f);
+
+  delete_PairIntFloat(pair);
+}
+
 TEST_CASE("Test c auto bind stl string", "[bind][c][stl][string]") {
   const auto str = new_String();
   const auto created_ref = String{str.ptr, false};
diff --git a/test/pytest/c/translators/pytest_c_translators_stl_std_pair.py b/test/pytest/c/translators/pytest_c_translators_stl_std_pair.py
index 4bc31ac7..3fa458fc 100644
--- a/test/pytest/c/translators/pytest_c_translators_stl_std_pair.py
+++ b/test/pytest/c/translators/pytest_c_translators_stl_std_pair.py
@@ -100,6 +100,13 @@ PairIntPairFloatC_NsImageInfo new_PairIntPairFloatC_NsImageInfo() {
   return c_pair;
 }
 
+PairIntPairFloatC_NsImageInfo new_PairIntPairFloatC_NsImageInfo_field(int first, PairFloatC_NsImageInfo second) {
+  return {
+    new std::pair<int, std::pair<float, ns::ImageInfo>>(first, *reinterpret_cast<std::pair<float, ns::ImageInfo> *>(second.ptr)),
+    true
+  };
+}
+
 void delete_PairIntPairFloatC_NsImageInfo(PairIntPairFloatC_NsImageInfo c_pair) {
   if (c_pair.mem_owner) {
     delete reinterpret_cast<std::pair<int, std::pair<float, ns::ImageInfo>> *>(c_pair.ptr);
@@ -142,12 +149,12 @@ PairFloatC_NsImageInfo PairIntPairFloatC_NsImageInfo_get_second(PairIntPairFloat
   return { new std::pair<float, ns::ImageInfo>(value), true };
 }
 
-void PairIntPairFloatC_NsImageInfo_set_first(PairIntPairFloatC_NsImageInfo c_pair, int value) {
-  reinterpret_cast<std::pair<int, std::pair<float, ns::ImageInfo>> *>(c_pair.ptr)->first = value;
+void PairIntPairFloatC_NsImageInfo_set_first(PairIntPairFloatC_NsImageInfo c_pair, int first) {
+  reinterpret_cast<std::pair<int, std::pair<float, ns::ImageInfo>> *>(c_pair.ptr)->first = first;
 }
 
-void PairIntPairFloatC_NsImageInfo_set_second(PairIntPairFloatC_NsImageInfo c_pair, PairFloatC_NsImageInfo value) {
-  reinterpret_cast<std::pair<int, std::pair<float, ns::ImageInfo>> *>(c_pair.ptr)->second = *reinterpret_cast<std::pair<float, ns::ImageInfo> *>(value.ptr);
+void PairIntPairFloatC_NsImageInfo_set_second(PairIntPairFloatC_NsImageInfo c_pair, PairFloatC_NsImageInfo second) {
+  reinterpret_cast<std::pair<int, std::pair<float, ns::ImageInfo>> *>(c_pair.ptr)->second = *reinterpret_cast<std::pair<float, ns::ImageInfo> *>(second.ptr);
 }
 """
     )
-- 
GitLab


From 83a7b0ba6421963354ff23168c0cb4fce71cca28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E7=A5=A5=E6=B3=BD?= <xiangze.li@aqrose.com>
Date: Wed, 15 Jan 2025 07:18:48 +0000
Subject: [PATCH 3/3] Apply 1 suggestion(s) to 1 file(s)

---
 src/cpp/stl/std_map.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/cpp/stl/std_map.py b/src/cpp/stl/std_map.py
index 1e065318..09a1191c 100644
--- a/src/cpp/stl/std_map.py
+++ b/src/cpp/stl/std_map.py
@@ -166,7 +166,7 @@ inline void {stl_type_name}::erase(const {key_type_name} & key) {{
   {c_stl_type_name}_erase(self_, {key_cpp_to_c});
 }}
 
-inline {stl_type_name}::{stl_type_name}(const std::initializer_list<std::pair<const {key_type_name}, {value_type_name}>> list) {{
+inline {stl_type_name}::{stl_type_name}(std::initializer_list<std::pair<const {key_type_name}, {value_type_name}>> list) {{
   self_ = new_{c_stl_type_name}();
   for (const auto &[key, value] : list) {{
     this->insert(key, value);
-- 
GitLab