From 165c3a690c6c44d0af391cb40bbbb6ee9b0ca55a Mon Sep 17 00:00:00 2001 From: M-Herr <75709772+M-Herr@users.noreply.github.com> Date: Tue, 20 May 2025 15:24:03 -0500 Subject: [PATCH] Added interface file includes for C++ types supported by swig (#1853) * Added interface file includes for C++ types supported by swig * Testing swig interface includes * Inital pass at testing STL access via input file for swig interface file update * Updated test comparison for keys() return function that swig generates for std::map. Added SIM_test_ip_stl to the trickops yml file * Updated trick_swig.i to remove redundant includes * Renamed input file for SIM_test_ip_stL * Added typemap so swig can convert from C++ std::string pointer to python string * Commented out some %include .i files. Also commented out %import for unordered_map as not supported by swig3 in the test code. * Removed duplicated includes and added checking swig version for some .i files. * Moved std_sstream.i to the right place as the order matters. * Moved all work in progress .i files in swig 3 to swig 4 block. * Removed unused files and added proper purposes for header files. * Updated vector of char16_t and char32_t tests. --------- Co-authored-by: Hong Chen Co-authored-by: mherr --- include/trick/swig/trick_swig.i | 48 ++++- test/SIM_test_ip/RUN_test/unit_test.py | 6 +- test/SIM_test_ip_stl/RUN_test/test_arrays.py | 172 +++++++++++++++++ test/SIM_test_ip_stl/RUN_test/test_vectors.py | 179 ++++++++++++++++++ test/SIM_test_ip_stl/RUN_test/unit_test.py | 20 ++ test/SIM_test_ip_stl/S_define | 17 ++ test/SIM_test_ip_stl/S_overrides.mk | 2 + test/SIM_test_ip_stl/models/STLIPTest.hh | 104 ++++++++++ .../test_classes/include/container_types.hh | 88 +++++++++ test_sims.yml | 7 + 10 files changed, 638 insertions(+), 5 deletions(-) create mode 100644 test/SIM_test_ip_stl/RUN_test/test_arrays.py create mode 100644 test/SIM_test_ip_stl/RUN_test/test_vectors.py create mode 100644 test/SIM_test_ip_stl/RUN_test/unit_test.py create mode 100644 test/SIM_test_ip_stl/S_define create mode 100644 test/SIM_test_ip_stl/S_overrides.mk create mode 100644 test/SIM_test_ip_stl/models/STLIPTest.hh create mode 100644 test/SIM_test_ip_stl/models/test_classes/include/container_types.hh diff --git a/include/trick/swig/trick_swig.i b/include/trick/swig/trick_swig.i index 97901753..5d9d9c2c 100644 --- a/include/trick/swig/trick_swig.i +++ b/include/trick/swig/trick_swig.i @@ -1,9 +1,54 @@ - /* include support for STLs */ + +%include "std_alloc.i" +%include "std_char_traits.i" + +%include "std_complex.i" +%include "std_deque.i" +%include "std_except.i" + %include "std_list.i" %include "std_map.i" +%include "std_multimap.i" +%include "std_multiset.i" + +%include "std_pair.i" +%include "std_set.i" + +#if SWIG_VERSION >= 0x040000 +// std_sstream.i is not fully supported and reliable in swig 3.0.x and is fully supported in swig 4.x +%include "std_sstream.i" +#endif %include "std_string.i" +%include "std_iostream.i" + %include "std_vector.i" + +%include "std_array.i" +%include "std_shared_ptr.i" +%include "std_unique_ptr.i" + +%include "std_container.i" + +// Both std_queue.i and std_stack.i coming with swig are wrappers for Ruby. +// We need to come up with our own wrappers for these if needed for Python. +//%include "std_queue.i" +//%include "std_stack.i" + +#if SWIG_VERSION >= 0x040000 +// All following std_unordered_.i files were work in progress in swig 3.0.x and are fully supported in swig 4.x +%include "std_unordered_map.i" +%include "std_unordered_multimap.i" +%include "std_unordered_multiset.i" +%include "std_unordered_set.i" +#endif +%include "std_vectora.i" + +#if SWIG_VERSION >= 0x040000 +// std_wstring.i was introduced in swig 3.0.8 but its support for Python was incomplete +// std_wstring.i works properly in swig 4.x +%include "std_wstring.i" +#endif %include "factory.i" %include "trick/swig/swig_extend_str.i" @@ -24,7 +69,6 @@ %{ #include - #include "trick/UnitsMap.hh" #include "trick/MemoryManager.hh" #include "trick/reference.h" diff --git a/test/SIM_test_ip/RUN_test/unit_test.py b/test/SIM_test_ip/RUN_test/unit_test.py index 4e17fcb5..7bf0c2db 100644 --- a/test/SIM_test_ip/RUN_test/unit_test.py +++ b/test/SIM_test_ip/RUN_test/unit_test.py @@ -2972,11 +2972,11 @@ def main(): test_so.obj.msi['key1'] = 50 test_so.obj.msi['key2'] = 60 test_so.obj.msi['key3'] = 70 - + TRICK_EXPECT_EQ( test_so.obj.msi.empty(), 0, test_suite , "STL map empty false" ) TRICK_EXPECT_EQ( test_so.obj.msi['key1'], 50, test_suite , "STL map key/data insertion/access" ) - TRICK_EXPECT_EQ( str(test_so.obj.msi.keys()), "['key1', 'key2', 'key3']", test_suite , "STL map keys command" ) - TRICK_EXPECT_EQ( str(test_so.obj.msi.values()), "[50, 60, 70]", test_suite , "STL map values command" ) + TRICK_EXPECT_EQ( list(str(k) for k in test_so.obj.msi.keys()), ['key1', 'key2', 'key3'], test_suite , "STL map keys command" ) + TRICK_EXPECT_EQ( test_so.obj.msi.values(), [50, 60, 70], test_suite , "STL map values command" ) TRICK_EXPECT_EQ( test_so.obj.msi.has_key('key1'), 1, test_suite , "STL map has_key true" ) TRICK_EXPECT_EQ( test_so.obj.msi.has_key('key4'), 0, test_suite , "STL map has_key false" ) TRICK_EXPECT_EQ( test_so.obj.msi.size(), 3, test_suite , "STL map size command" ) diff --git a/test/SIM_test_ip_stl/RUN_test/test_arrays.py b/test/SIM_test_ip_stl/RUN_test/test_arrays.py new file mode 100644 index 00000000..e0f10464 --- /dev/null +++ b/test/SIM_test_ip_stl/RUN_test/test_arrays.py @@ -0,0 +1,172 @@ +from trick.unit_test import * + +def array_tests(stl_so, test_suite): + test_name = "Char Arrays" + stl_so.stl_ip_test.char_types.array[0] = 'a' + stl_so.stl_ip_test.char_types.array[1] = 'b' + stl_so.stl_ip_test.char_types.array[2] = 'c' + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.char_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.array[0], 'a', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.array[1], 'b', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.array[2], 'c', test_suite, test_name) + + try: + test_name = "Char Arrays" + stl_so.stl_ip_test.char_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "Signed Char Arrays" + stl_so.stl_ip_test.signed_char_types.array[0] = -1 + stl_so.stl_ip_test.signed_char_types.array[1] = -2 + stl_so.stl_ip_test.signed_char_types.array[2] = -3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.signed_char_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.array[0], -1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.array[1], -2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.array[2], -3, test_suite, test_name) + try: + test_name = "Signed Char Arrays" + stl_so.stl_ip_test.signed_char_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "Unsigned Char Arrays" + stl_so.stl_ip_test.unsigned_char_types.array[0] = 1 + stl_so.stl_ip_test.unsigned_char_types.array[1] = 2 + stl_so.stl_ip_test.unsigned_char_types.array[2] = 3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.unsigned_char_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.array[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.array[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.array[2], 3, test_suite, test_name) + try: + test_name = "Unsigned Char Arrays" + stl_so.stl_ip_test.unsigned_char_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + #TODO: Fix test for char16_t + ''' + test_name = "char16_t Arrays" + stl_so.stl_ip_test.char16_t_types.array[0] = stl_so.stl_ip_test.to_char16_t('a') + stl_so.stl_ip_test.char16_t_types.array[1] = stl_so.stl_ip_test.to_char16_t('b') + stl_so.stl_ip_test.char16_t_types.array[2] = stl_so.stl_ip_test.to_char16_t('c') + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.char16_t_types.array), 3, test_suite, test_name) + + try: + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char16_t_types.array[0], stl_so.stl_ip_test.to_char16_t('a'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char16_t_types.array[1], stl_so.stl_ip_test.to_char16_t('b'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char16_t_types.array[2], stl_so.stl_ip_test.to_char16_t('c'), test_suite, test_name) + except Exception as e: + print(f"Exception {e}") + + try: + test_name = "char16_t Arrays" + stl_so.stl_ip_test.char16_t_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + + test_name = "char32_t Arrays" + stl_so.stl_ip_test.char32_t_types.array[0] = 'a' + stl_so.stl_ip_test.char32_t_types.array[1] = 'b' + stl_so.stl_ip_test.char32_t_types.array[2] = 'c' + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.char32_t_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char32_t_types.array[0], 'a', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char32_t_types.array[1], 'b', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char32_t_types.array[2], 'c', test_suite, test_name) + try: + test_name = "char32_t Arrays" + stl_so.stl_ip_test.char32_t_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + ''' + + test_name = "short int Arrays" + stl_so.stl_ip_test.short_int_types.array[0] = 1 + stl_so.stl_ip_test.short_int_types.array[1] = 2 + stl_so.stl_ip_test.short_int_types.array[2] = 3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.short_int_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.array[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.array[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.array[2], 3, test_suite, test_name) + try: + test_name = "short int Arrays" + stl_so.stl_ip_test.short_int_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "unsigned short int Arrays" + stl_so.stl_ip_test.unsigned_short_int_types.array[0] = 1 + stl_so.stl_ip_test.unsigned_short_int_types.array[1] = 2 + stl_so.stl_ip_test.unsigned_short_int_types.array[2] = 3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.unsigned_short_int_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.array[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.array[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.array[2], 3, test_suite, test_name) + #Pass invalid type(struct) + try: + test_name = "unsigned short int Arrays" + stl_so.stl_ip_test.unsigned_short_int_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + #Pass invalid type(signed value) + try: + test_name = "unsigned short int Arrays" + stl_so.stl_ip_test.unsigned_short_int_types.array[0] = -1 + + except Exception as e: + print(f"Expected exception due to passing signed value into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + + test_name = "int Arrays" + stl_so.stl_ip_test.int_types.array[0] = 1 + stl_so.stl_ip_test.int_types.array[1] = 2 + stl_so.stl_ip_test.int_types.array[2] = 3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.int_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.array[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.array[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.array[2], 3, test_suite, test_name) + + try: + test_name = "int Arrays" + stl_so.stl_ip_test.int_types.array[0] = trick.TestStructure() + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + test_name = "unsigned int Arrays" + stl_so.stl_ip_test.unsigned_int_types.array[0] = 1 + stl_so.stl_ip_test.unsigned_int_types.array[1] = 2 + stl_so.stl_ip_test.unsigned_int_types.array[2] = 3 + TRICK_EXPECT_EQ(len(stl_so.stl_ip_test.unsigned_int_types.array), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.array[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.array[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.array[2], 3, test_suite, test_name) + #Pass invalid type(struct) + try: + test_name = "unsigned int Arrays" + stl_so.stl_ip_test.unsigned_int_types.array[0] = trick.TestStructure() + + except Exception as e: + print(f"Expected exception due to passing TestStruct into std::array : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) \ No newline at end of file diff --git a/test/SIM_test_ip_stl/RUN_test/test_vectors.py b/test/SIM_test_ip_stl/RUN_test/test_vectors.py new file mode 100644 index 00000000..07d85bb8 --- /dev/null +++ b/test/SIM_test_ip_stl/RUN_test/test_vectors.py @@ -0,0 +1,179 @@ +from trick.unit_test import * + +def vector_tests(stl_so, test_suite): + test_name = "Char Vectors" + stl_so.stl_ip_test.char_types.vector.push_back('a') + stl_so.stl_ip_test.char_types.vector.push_back('b') + stl_so.stl_ip_test.char_types.vector.push_back('c') + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.vector[0], 'a', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.vector[1], 'b', test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char_types.vector[2], 'c', test_suite, test_name) + + try: + test_name = "Char Vectors" + stl_so.stl_ip_test.char_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "Signed Char Vectors" + stl_so.stl_ip_test.signed_char_types.vector.push_back(-1) + stl_so.stl_ip_test.signed_char_types.vector.push_back(-2) + stl_so.stl_ip_test.signed_char_types.vector.push_back(-3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.vector[0], -1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.vector[1], -2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.signed_char_types.vector[2], -3, test_suite, test_name) + try: + test_name = "Signed Char Vectors" + stl_so.stl_ip_test.char_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "Unsigned Char Vectors" + stl_so.stl_ip_test.unsigned_char_types.vector.push_back(1) + stl_so.stl_ip_test.unsigned_char_types.vector.push_back(2) + stl_so.stl_ip_test.unsigned_char_types.vector.push_back(3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.vector[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.vector[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_char_types.vector[2], 3, test_suite, test_name) + try: + test_name = "Unsigned Char Vectors" + stl_so.stl_ip_test.char_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "char16_t Vectors" + ''' + # Calling push_back on char16_t vector directly here causes issues due to char16_t not supported in python + stl_so.stl_ip_test.char16_t_types.vector.push_back(stl_so.stl_ip_test.to_char16_t('a')) + stl_so.stl_ip_test.char16_t_types.vector.push_back(stl_so.stl_ip_test.to_char16_t('b')) + stl_so.stl_ip_test.char16_t_types.vector.push_back(stl_so.stl_ip_test.to_char16_t('c')) + ''' + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char16_t_types.vector, ord('a')) + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char16_t_types.vector, ord('b')) + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char16_t_types.vector, ord('c')) + + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char16_t_types.vector.size(), 3, test_suite, test_name) + + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char16_t_types.vector, 0), ord('a'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char16_t_types.vector, 1), ord('b'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char16_t_types.vector, 2), ord('c'), test_suite, test_name) + + try: + test_name = "char16_t Vectors" + stl_so.stl_ip_test.char16_t_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "char32_t Vectors" + ''' + # Calling push_back on char32_t vector directly here causes issues due to char32_t not supported in python + stl_so.stl_ip_test.char32_t_types.vector.push_back(stl_so.stl_ip_test.to_char32_t(ord('a'))) + stl_so.stl_ip_test.char32_t_types.vector.push_back(stl_so.stl_ip_test.to_char32_t(ord('b'))) + stl_so.stl_ip_test.char32_t_types.vector.push_back(stl_so.stl_ip_test.to_char32_t(ord('c'))) + ''' + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char32_t_types.vector, ord('a')) + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char32_t_types.vector, ord('b')) + stl_so.stl_ip_test.addCharToVector(stl_so.stl_ip_test.char32_t_types.vector, ord('c')) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.char32_t_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char32_t_types.vector, 0), ord('a'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char32_t_types.vector, 1), ord('b'), test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.getCharFromVector(stl_so.stl_ip_test.char32_t_types.vector, 2), ord('c'), test_suite, test_name) + try: + test_name = "char32_t Vectors" + stl_so.stl_ip_test.char32_t_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + test_name = "short int Vectors" + stl_so.stl_ip_test.short_int_types.vector.push_back(1) + stl_so.stl_ip_test.short_int_types.vector.push_back(2) + stl_so.stl_ip_test.short_int_types.vector.push_back(3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.vector[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.vector[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.short_int_types.vector[2], 3, test_suite, test_name) + try: + test_name = "short int Vectors" + stl_so.stl_ip_test.short_int_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + test_name = "unsigned short int Vectors" + stl_so.stl_ip_test.unsigned_short_int_types.vector.push_back(1) + stl_so.stl_ip_test.unsigned_short_int_types.vector.push_back(2) + stl_so.stl_ip_test.unsigned_short_int_types.vector.push_back(3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.vector[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.vector[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_short_int_types.vector[2], 3, test_suite, test_name) + #Pass invalid type(struct) + try: + test_name = "unsigned short int Vectors" + stl_so.stl_ip_test.unsigned_short_int_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + #Pass invalid type(signed value) + try: + test_name = "unsigned short int Vectors" + stl_so.stl_ip_test.unsigned_short_int_types.vector.push_back(-1) + + except Exception as e: + print(f"Expected exception due to passing signed value into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + + + test_name = "int Vectors" + stl_so.stl_ip_test.int_types.vector.push_back(1) + stl_so.stl_ip_test.int_types.vector.push_back(2) + stl_so.stl_ip_test.int_types.vector.push_back(3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.vector[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.vector[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.int_types.vector[2], 3, test_suite, test_name) + + try: + test_name = "int Vectors" + stl_so.stl_ip_test.int_types.vector.push_back(trick.TestStructure()) + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) + + test_name = "unsigned int Vectors" + stl_so.stl_ip_test.unsigned_int_types.vector.push_back(1) + stl_so.stl_ip_test.unsigned_int_types.vector.push_back(2) + stl_so.stl_ip_test.unsigned_int_types.vector.push_back(3) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.vector.size(), 3, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.vector[0], 1, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.vector[1], 2, test_suite, test_name) + TRICK_EXPECT_EQ(stl_so.stl_ip_test.unsigned_int_types.vector[2], 3, test_suite, test_name) + #Pass invalid type(struct) + try: + test_name = "unsigned int Vectors" + stl_so.stl_ip_test.unsigned_int_types.vector.push_back(trick.TestStructure()) + + except Exception as e: + print(f"Expected exception due to passing TestStruct into push_back for std::vector : {e}") + TRICK_EXPECT_GT(len(e.__str__()), 0, test_suite, test_name) diff --git a/test/SIM_test_ip_stl/RUN_test/unit_test.py b/test/SIM_test_ip_stl/RUN_test/unit_test.py new file mode 100644 index 00000000..ff29a2ab --- /dev/null +++ b/test/SIM_test_ip_stl/RUN_test/unit_test.py @@ -0,0 +1,20 @@ +import trick + +from trick.unit_test import * +trick_utest.unit_tests.enable() +trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM_test_ip_stl.xml" ) +trick_utest.unit_tests.set_test_name( "InputFileSTLTests" ) + + + +test_suite = "STL input tests" + +from RUN_test.test_arrays import * +from RUN_test.test_vectors import * + +array_tests(stl_so, test_suite) +vector_tests(stl_so, test_suite) + + +trick.stop(10) + diff --git a/test/SIM_test_ip_stl/S_define b/test/SIM_test_ip_stl/S_define new file mode 100644 index 00000000..658e6810 --- /dev/null +++ b/test/SIM_test_ip_stl/S_define @@ -0,0 +1,17 @@ +#include "sim_objects/default_trick_sys.sm" + +##include "STLIPTest.hh" + +class STLSimObject : public Trick::SimObject +{ + public: + STLIPTest stl_ip_test; + + STLSimObject() + { + + } +}; + + +STLSimObject stl_so; \ No newline at end of file diff --git a/test/SIM_test_ip_stl/S_overrides.mk b/test/SIM_test_ip_stl/S_overrides.mk new file mode 100644 index 00000000..d94d3b87 --- /dev/null +++ b/test/SIM_test_ip_stl/S_overrides.mk @@ -0,0 +1,2 @@ +TRICK_CFLAGS += -I./models +TRICK_CXXFLAGS += -I./models diff --git a/test/SIM_test_ip_stl/models/STLIPTest.hh b/test/SIM_test_ip_stl/models/STLIPTest.hh new file mode 100644 index 00000000..b6bfa68c --- /dev/null +++ b/test/SIM_test_ip_stl/models/STLIPTest.hh @@ -0,0 +1,104 @@ +/* + PURPOSE: (Defines the STLIPTest class, which serves as a testbed for various STL + container types instantiated with C++ types such as int, double, char, etc.) + LIBRARY_DEPENDENCIES: ( + () + ) +*/ + +#ifndef STL_IP_TEST_HH +#define STL_IP_TEST_HH + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include "test_classes/include/container_types.hh" + +struct TestStructure +{ + int a; + double b; + +}; + +class STLIPTest +{ + friend class InputProcessor; + + public: + STLIPTest() = default; + ~STLIPTest() = default; + + //STLs + //Char Types + + //inline char16_t to_char16_t(char c) {return static_cast(c);} + + // Python doesn't have a char16_t type, so we use int for compatibility + // Add a character to the vector (accepts int for Python compatibility) + void addCharToVector(std::vector& vec, int value) { + vec.push_back(static_cast(value)); + } + // Get a character from the vector (returns as int for Python compatibility) + int getCharFromVector(std::vector& vec, size_t index) { + if (index >= vec.size()) { + // Handle out of bounds access + throw std::out_of_range("Index out of bounds"); + } + // Convert char16_t to int when returning to Python + return static_cast(vec[index]); + } + + // Python doesn't have a char32_t type, so we use int for compatibility + // Add a character to the vector (accepts int for Python compatibility) + void addCharToVector(std::vector& vec, int value) { + vec.push_back(static_cast(value)); + } + // Get a character from the vector (returns as int for Python compatibility) + int getCharFromVector(std::vector& vec, size_t index) { + if (index >= vec.size()) { + // Handle out of bounds access + throw std::out_of_range("Index out of bounds"); + } + // Convert char16_t to int when returning to Python + return static_cast(vec[index]); + } + + STLContainerTypes char_types; + STLContainerTypes signed_char_types; + STLContainerTypes unsigned_char_types; + STLContainerTypes char16_t_types; + STLContainerTypes char32_t_types; + STLContainerTypes short_int_types; + STLContainerTypes unsigned_short_int_types; + STLContainerTypes int_types; + STLContainerTypes unsigned_int_types; + STLContainerTypes long_int_types; + STLContainerTypes unsigned_long_int_types; + STLContainerTypes long_long_int_types; + STLContainerTypes unsigned_long_long_int_types; + STLContainerTypes float_types; + STLContainerTypes double_types; + STLContainerTypes long_double_types; +}; + +#endif \ No newline at end of file diff --git a/test/SIM_test_ip_stl/models/test_classes/include/container_types.hh b/test/SIM_test_ip_stl/models/test_classes/include/container_types.hh new file mode 100644 index 00000000..91b5a343 --- /dev/null +++ b/test/SIM_test_ip_stl/models/test_classes/include/container_types.hh @@ -0,0 +1,88 @@ +/* + PURPOSE: (Provides a convenient way to instantiate and use a variety of STL containers + for C++ types/language bindings with SWIG) + LIBRARY_DEPENDENCIES: ( + () + ) +*/ + + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#ifdef SWIG +%define DECLARE_SWIG_CONTAINER_TYPES(ALIAS, TYPE) +%template(ALIAS##Array) std::array; +%template(ALIAS##Vector) std::vector; +// Both std_queue.i and std_stack.i coming with swig are wrappers for Ruby. +// We need to come up with our own wrappers for these if needed for Python. +//%template(ALIAS##Queue) std::queue; +//%template(ALIAS##Stack) std::stack; +%template(ALIAS##Deque) std::deque; +%template(ALIAS##Set) std::set; +%template(ALIAS##Map) std::map; +#if SWIG_VERSION >= 0x040000 +%template(ALIAS##UnorderedMap) std::unordered_map; +#endif +%enddef + +DECLARE_SWIG_CONTAINER_TYPES(Char, char) +DECLARE_SWIG_CONTAINER_TYPES(SignedChar, signed char) +DECLARE_SWIG_CONTAINER_TYPES(UnsignedChar, unsigned char) +DECLARE_SWIG_CONTAINER_TYPES(Char16T, char16_t) +DECLARE_SWIG_CONTAINER_TYPES(Char32T, char32_t) +DECLARE_SWIG_CONTAINER_TYPES(ShortInt, short int) +DECLARE_SWIG_CONTAINER_TYPES(UnsignedShortInt, unsigned short int) +DECLARE_SWIG_CONTAINER_TYPES(Int, int) +DECLARE_SWIG_CONTAINER_TYPES(UnsignedInt, unsigned int) +DECLARE_SWIG_CONTAINER_TYPES(LongInt, long int) +DECLARE_SWIG_CONTAINER_TYPES(UnsignedLongInt, unsigned long int) +DECLARE_SWIG_CONTAINER_TYPES(LongLongInt, long long int) +DECLARE_SWIG_CONTAINER_TYPES(UnsignedLongLongInt, unsigned long long int) +DECLARE_SWIG_CONTAINER_TYPES(Float, float) +DECLARE_SWIG_CONTAINER_TYPES(Double, double) +DECLARE_SWIG_CONTAINER_TYPES(LongDouble, long double) + +#endif + + +template +struct STLContainerTypes +{ + using ArrayType = std::array; + using VectorType = std::vector; + using QueueType = std::queue; + using DequeType = std::deque; + using SetType = std::set; + using MapType = std::map; + using UnorderedMapType = std::unordered_map; + using StackType = std::stack; + + ArrayType array; + VectorType vector; + QueueType queue; + DequeType deque; + SetType set; + MapType map; + UnorderedMapType unordered_map; + StackType stack; + +}; + diff --git a/test_sims.yml b/test_sims.yml index 0b667638..916e58f3 100644 --- a/test_sims.yml +++ b/test_sims.yml @@ -93,6 +93,13 @@ SIM_test_ip: runs: RUN_test/unit_test.py: returns: 0 +SIM_test_ip_stl: + path: test/SIM_test_ip_stl + build_args: "-t" + binary: "T_main_{cpu}_test.exe" + runs: + RUN_test/unit_test.py: + returns: 0 SIM_test_multidt: path: test/SIM_test_multidt build_args: "-t"