mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-19 04:22:13 +00:00
268 lines
7.7 KiB
Python
268 lines
7.7 KiB
Python
# Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
|
|
#
|
|
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
|
# Initial implementation by Bela Schaum, https://github.com/schaumb
|
|
# The way to make it union and UB free by X-Ryl669, https://github.com/X-Ryl669
|
|
#
|
|
|
|
############################################################################################################################
|
|
|
|
import sys
|
|
import string
|
|
import random
|
|
|
|
# a bigger value might lead to compiler out of heap space error on MSVC
|
|
STRUCT_COUNT = 50
|
|
MAX_FIELD_COUNT = 50
|
|
|
|
MAIN_TEMPLATE = """// Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov, Antony Polukhin.
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// Generated by misc/generate_fields_names_big.cpp.py
|
|
|
|
#include <boost/pfr/core_name.hpp>
|
|
#include <type_traits>
|
|
|
|
#include <boost/core/lightweight_test.hpp>
|
|
|
|
namespace testing {
|
|
|
|
template <class... Types>
|
|
auto make_stdarray(const Types&... t) {
|
|
return std::array<std::common_type_t<Types...>, sizeof...(Types)>{t...};
|
|
}
|
|
|
|
%STRUCTS_LIST%
|
|
|
|
%TEST_GET_NAME_DEFINITIONS_LIST%
|
|
|
|
%TEST_GET_NAMES_AS_ARRAY_DEFINITIONS_LIST%
|
|
|
|
|
|
} // namespace testing
|
|
|
|
int main() {
|
|
%TEST_GET_NAME_CALLS_LIST%
|
|
%TEST_GET_NAMES_AS_ARRAY_CALLS_LIST%
|
|
|
|
return boost::report_errors();
|
|
}
|
|
"""
|
|
|
|
STRUCT_TEMPLATE = """struct Aggregate%STRUCT_ID% {
|
|
%FIELD_DEFINITIONS_LIST%
|
|
};
|
|
"""
|
|
|
|
STRUCT_FIELD_DEFINITION_TEMPLATE = """int %FIELD_NAME%;
|
|
"""
|
|
|
|
TEST_GET_NAME_TEMPLATE = """void test_get_name_%TEST_ID%() {
|
|
%CHECKERS_LIST%
|
|
}
|
|
"""
|
|
|
|
TEST_GET_NAME_CHECKER_TEMPLATE = """BOOST_TEST_EQ( ((boost::pfr::get_name<%FIELD_ID%, Aggregate%STRUCT_ID%>())), "%FIELD_NAME%");
|
|
"""
|
|
|
|
TEST_GET_NAMES_AS_ARRAY_TEMPLATE = """void test_names_as_array_%TEST_ID%() {
|
|
const auto expected = make_stdarray(
|
|
%FIELD_NAMES_LIST%
|
|
);
|
|
const auto value = boost::pfr::names_as_array<Aggregate%STRUCT_ID%>();
|
|
BOOST_TEST_EQ(expected.size(), value.size());
|
|
for (std::size_t i=0;i<expected.size();++i) {
|
|
BOOST_TEST_EQ(value[i], expected[i]);
|
|
}
|
|
}
|
|
"""
|
|
|
|
FIELD_NAME_TEMPLATE = """std::string_view{"%FIELD_NAME%"}
|
|
"""
|
|
|
|
TEST_GET_NAME_CALL_TEMPLATE = """testing::test_get_name_%TEST_ID%();
|
|
"""
|
|
|
|
TEST_GET_NAMES_AS_ARRAY_CALL_TEMPLATE = """testing::test_names_as_array_%TEST_ID%();
|
|
"""
|
|
|
|
############################################################################################################################
|
|
|
|
field_names = {
|
|
"alignas": True,
|
|
"alignof": True,
|
|
"and": True,
|
|
"and_eq": True,
|
|
"asm": True,
|
|
"atomic_cancel": True,
|
|
"atomic_commit": True,
|
|
"atomic_noexcept": True,
|
|
"auto": True,
|
|
"bitand": True,
|
|
"bitor": True,
|
|
"bool": True,
|
|
"break": True,
|
|
"case": True,
|
|
"catch": True,
|
|
"char": True,
|
|
"char8_t": True,
|
|
"char16_t": True,
|
|
"char32_t": True,
|
|
"class": True,
|
|
"compl": True,
|
|
"concept": True,
|
|
"const": True,
|
|
"consteval": True,
|
|
"constexpr": True,
|
|
"constinit": True,
|
|
"const_cast": True,
|
|
"continue": True,
|
|
"co_await": True,
|
|
"co_return": True,
|
|
"co_yield": True,
|
|
"decltype": True,
|
|
"default": True,
|
|
"delete": True,
|
|
"do": True,
|
|
"double": True,
|
|
"dynamic_cast": True,
|
|
"else": True,
|
|
"enum": True,
|
|
"explicit": True,
|
|
"export": True,
|
|
"extern": True,
|
|
"false": True,
|
|
"float": True,
|
|
"for": True,
|
|
"friend": True,
|
|
"goto": True,
|
|
"if": True,
|
|
"inline": True,
|
|
"int": True,
|
|
"long": True,
|
|
"mutable": True,
|
|
"namespace": True,
|
|
"new": True,
|
|
"noexcept": True,
|
|
"not": True,
|
|
"not_eq": True,
|
|
"nullptr": True,
|
|
"operator": True,
|
|
"or": True,
|
|
"or_eq": True,
|
|
"private": True,
|
|
"protected": True,
|
|
"public": True,
|
|
"reflexpr": True,
|
|
"register": True,
|
|
"reinterpret_cast": True,
|
|
"requires": True,
|
|
"return": True,
|
|
"short": True,
|
|
"signed": True,
|
|
"sizeof": True,
|
|
"static": True,
|
|
"static_assert": True,
|
|
"static_cast": True,
|
|
"struct": True,
|
|
"switch": True,
|
|
"synchronized": True,
|
|
"template": True,
|
|
"this": True,
|
|
"thread_local": True,
|
|
"throw": True,
|
|
"true": True,
|
|
"try": True,
|
|
"typedef": True,
|
|
"typeid": True,
|
|
"typename": True,
|
|
"union": True,
|
|
"unsigned": True,
|
|
"using": True,
|
|
"virtual": True,
|
|
"void": True,
|
|
"volatile": True,
|
|
"wchar_t": True,
|
|
"while": True,
|
|
"xor": True,
|
|
"xor_eq": True
|
|
}
|
|
field_names_by_id = {}
|
|
|
|
def generate_new_field_name():
|
|
result = ''
|
|
name_len = random.randint(1,100)
|
|
result += random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")
|
|
for i in range(name_len-1):
|
|
result += random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")
|
|
return result
|
|
|
|
def generate_field_name(struct_id, field_id):
|
|
key = (struct_id, field_id)
|
|
if not key in field_names_by_id:
|
|
new_name = generate_new_field_name()
|
|
while new_name in field_names:
|
|
new_name = generate_new_field_name()
|
|
field_names[new_name] = True
|
|
field_names_by_id[key] = new_name
|
|
return field_names_by_id[key]
|
|
|
|
def generate_struct(struct_id):
|
|
field_definitions = ''
|
|
fields_count = struct_id
|
|
for i in range(fields_count):
|
|
field_definitions += STRUCT_FIELD_DEFINITION_TEMPLATE.replace('%FIELD_NAME%', generate_field_name(struct_id, i))
|
|
return STRUCT_TEMPLATE.replace('%FIELD_DEFINITIONS_LIST%', field_definitions).replace('%STRUCT_ID%', str(struct_id))
|
|
|
|
def generate_structs_list():
|
|
result = ''
|
|
for i in range(STRUCT_COUNT):
|
|
result += generate_struct(i+1)
|
|
return result
|
|
|
|
def generate_test_get_name_definition(struct_id):
|
|
checkers_list = ''
|
|
fields_count = struct_id
|
|
for i in range(fields_count):
|
|
checkers_list += TEST_GET_NAME_CHECKER_TEMPLATE.replace('%FIELD_ID%', str(i)).replace('%STRUCT_ID%', str(struct_id)).replace('%FIELD_NAME%', generate_field_name(struct_id, i))
|
|
return TEST_GET_NAME_TEMPLATE.replace('%TEST_ID%', str(struct_id)).replace('%CHECKERS_LIST%', checkers_list)
|
|
|
|
def generate_test_get_name_definitions_list():
|
|
result = ''
|
|
for i in range(STRUCT_COUNT):
|
|
result += generate_test_get_name_definition(i+1)
|
|
return result
|
|
|
|
def generate_test_names_as_array_definition(struct_id):
|
|
field_names_list = FIELD_NAME_TEMPLATE.replace('%FIELD_NAME%', generate_field_name(struct_id, 0))
|
|
fields_count = struct_id
|
|
for i in range(1, fields_count):
|
|
field_names_list += ', ' + FIELD_NAME_TEMPLATE.replace('%FIELD_NAME%', generate_field_name(struct_id, i))
|
|
return TEST_GET_NAMES_AS_ARRAY_TEMPLATE.replace('%TEST_ID%', str(struct_id)).replace('%FIELD_NAMES_LIST%', field_names_list).replace('%STRUCT_ID%', str(struct_id))
|
|
|
|
def generate_test_names_as_array_definitions_list():
|
|
result = ''
|
|
for i in range(STRUCT_COUNT):
|
|
result += generate_test_names_as_array_definition(i+1)
|
|
return result
|
|
|
|
def generate_test_get_name_calls_list():
|
|
result = ''
|
|
for i in range(STRUCT_COUNT):
|
|
result += TEST_GET_NAME_CALL_TEMPLATE.replace('%TEST_ID%', str(i+1))
|
|
return result
|
|
|
|
def generate_test_names_as_array_calls_list():
|
|
result = ''
|
|
for i in range(STRUCT_COUNT):
|
|
result += TEST_GET_NAMES_AS_ARRAY_CALL_TEMPLATE.replace('%TEST_ID%', str(i+1))
|
|
return result
|
|
|
|
print(MAIN_TEMPLATE.replace('%STRUCTS_LIST%', generate_structs_list()).replace('%TEST_GET_NAME_DEFINITIONS_LIST%', generate_test_get_name_definitions_list()).replace('%TEST_GET_NAMES_AS_ARRAY_DEFINITIONS_LIST%', generate_test_names_as_array_definitions_list()).replace('%TEST_GET_NAME_CALLS_LIST%', generate_test_get_name_calls_list()).replace('%TEST_GET_NAMES_AS_ARRAY_CALLS_LIST%', generate_test_names_as_array_calls_list()))
|
|
|