includes = ["variant", "utility"] definitions = ''' struct Thrower { explicit Thrower(int) {} Thrower(const Thrower&) { throw std::domain_error("copy ctor"); } Thrower& operator=(const Thrower&) = default; }; ''' [cases] [cases.char_int64_1] param_types = ["const std::variant&"] setup = "return 'a';" expect_json = '''[{ "staticSize":16, "dynamicSize":0, "exclusiveSize":15, "length":1, "capacity":1, "elementStaticSize":8, "members":[ {"typeName":"int8_t", "staticSize":1, "exclusiveSize":1, "dynamicSize":0} ]}]''' expect_json_v2 = '''[{ "size":16, "staticSize":16, "exclusiveSize":15, "length":1, "capacity":1, "members":[ {"typeNames":["int8_t"], "size":1, "staticSize":1, "exclusiveSize":1} ] }]''' [cases.char_int64_2] param_types = ["const std::variant&"] setup = "return 1234;" expect_json = '''[{ "staticSize":16, "dynamicSize":0, "exclusiveSize":8, "length":1, "capacity":1, "elementStaticSize":8, "members":[ {"typeName":"int64_t", "staticSize":8, "exclusiveSize":8, "dynamicSize":0} ]}]''' expect_json_v2 = '''[{ "size":16, "staticSize":16, "exclusiveSize":8, "length":1, "capacity":1, "members":[ {"typeNames":["int64_t"], "size":8, "staticSize":8, "exclusiveSize":8} ] }]''' [cases.vector_int_1] param_types = ["const std::variant, int>&"] setup = "return std::vector{1,2,3};" expect_json = '''[{ "staticSize":32, "dynamicSize":12, "exclusiveSize":8, "length":1, "capacity":1, "elementStaticSize":24, "members":[ { "typeName":"std::vector>", "staticSize":24, "dynamicSize":12, "exclusiveSize":36, "length":3, "capacity":3, "elementStaticSize":4 } ]}]''' expect_json_v2 = '''[{ "size":44, "staticSize":32, "exclusiveSize":8, "length":1, "capacity":1, "members":[ {"typeNames":["std::vector>"], "size":36, "staticSize":24, "exclusiveSize":24, "members":[ {"typeNames":["int32_t"], "size":4, "staticSize":4, "exclusiveSize":4}, {"typeNames":["int32_t"], "size":4, "staticSize":4, "exclusiveSize":4}, {"typeNames":["int32_t"], "size":4, "staticSize":4, "exclusiveSize":4} ]} ] }]''' [cases.vector_int_2] param_types = ["const std::variant, int>&"] setup = "return 123;" expect_json = '''[{ "staticSize":32, "dynamicSize":0, "length":1, "capacity":1, "elementStaticSize":24, "members":[ { "typeName":"int32_t", "staticSize":4, "dynamicSize":0 } ]}]''' expect_json_v2 = '''[{ "size":32, "staticSize":32, "exclusiveSize":28, "length":1, "capacity":1, "members":[ {"typeNames":["int32_t"], "size":4, "staticSize":4, "exclusiveSize":4} ] }]''' [cases.optional] # This test case ensures that the alignment of std::variant is set # correctly, as otherwise the size of the std::optional would be wrong param_types = ["const std::optional>&"] setup = "return 123;" expect_json = '''[{ "staticSize":24, "dynamicSize":0, "exclusiveSize":8, "length":1, "capacity":1, "elementStaticSize":16, "members":[ { "staticSize":16, "dynamicSize":0, "exclusiveSize":8, "length":1, "capacity":1, "elementStaticSize":8, "members":[ {"typeName":"int64_t", "staticSize":8, "exclusiveSize":8, "dynamicSize":0} ] } ]}]''' expect_json_v2 = '''[{ "size":24, "staticSize":24, "exclusiveSize":8, "length":1, "capacity":1, "members":[{ "size":16, "staticSize":16, "exclusiveSize":8, "length":1, "capacity":1, "members":[ {"typeNames":["int64_t"], "size":8, "staticSize":8, "exclusiveSize":8} ] }] }]''' [cases.empty] # https://en.cppreference.com/w/cpp/utility/variant/valueless_by_exception param_types = ["const std::variant&"] setup = ''' std::variant var{123}; try { var = Thrower(456); } catch (const std::domain_error &ex) { // Ignore } return var; ''' expect_json = '''[{ "staticSize":8, "dynamicSize":0, "exclusiveSize":8, "length":1, "capacity":1, "elementStaticSize":4, "NOT":"members" }]''' expect_json_v2 = '''[{ "size":8, "staticSize":8, "exclusiveSize":8, "length":0, "capacity":1, "members":[] }]''' # With less than 256 options, parameter indexes are stored in a uint8_t and # the invalid index value is 0xff. These tests check that we regonise that # 0xff can be a valid index if there are at least 256 parameters, and that # the invalid index value is raised to 0xffff. [cases.256_params_256] param_types = ["const std::variant&"] setup = "return 'a';" expect_json = '''[{ "staticSize":8, "dynamicSize":0, "exclusiveSize":7, "length":1, "capacity":1, "elementStaticSize":4, "members":[ {"typeName":"int8_t", "staticSize":1, "exclusiveSize":1, "dynamicSize":0} ]}]''' expect_json_v2 = '''[{ "size":8, "staticSize":8, "exclusiveSize":7, "length":1, "capacity":1, "members":[ {"typeNames":["int8_t"], "size":1, "staticSize":1, "exclusiveSize":1} ] }]''' [cases.256_params_empty] param_types = ["const std::variant&"] setup = ''' std::variant var{'a'}; try { var = Thrower(456); } catch (const std::domain_error &ex) { // Ignore } return var; ''' expect_json = '''[{ "staticSize":8, "dynamicSize":0, "length":1, "capacity":1, "elementStaticSize":4, "NOT":"members" }]''' expect_json_v2 = '''[{ "size":8, "staticSize":8, "exclusiveSize":8, "length":0, "capacity":1, "members":[] }]'''