/
volodja
/
iridium
Обзор
Документация
Войти
/
volodja
/
iridium
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
source/test/convertion/convert.cpp
387 строк
13 KB
volodja
- parsing: json parser optimisation
04 авг 2026, 20:05
04 авг 2026, 20:05
57d8a5d
Код
Авторство
О чём код?
#include <iridium/testing/tester.h> #include <iridium/convertion/convert.h> //#include <iridium/caching/lazy_cacher.h> #include <iridium/platform.h> #include <iridium/enum.h> #include <string> #include <vector> #include <iostream> #include <typeinfo> #include <chrono> #include <functional> using namespace std; using std::chrono::duration_cast; using std::chrono::nanoseconds; using std::chrono::system_clock; enum TAnotherEnum { AE1 = 55, AE2 = 555 }; DEFINE_ENUM(TEnum, E1, E2, E3 = 5, E4 = AE1, E5) DEFINE_ENUM_CONVERT(TEnum) // IMPLEMENT_ENUM(TEnum) namespace iridium::convertion { //template<typename TValue> //TValue makeTestValue(int const &i); //template<> //int makeTestValue(int const &i) { // return i; // -----> //} //template<> //double makeTestValue(int const &i) { // return i / 5; // -----> //} //template<> //string makeTestValue(int const &i) { // return convert<string>(i); // -----> //} //template<typename TFrom, typename TTo> //void runBenchmark() { // cout << "convert" << endl // << "from: " << string(typeid(TFrom).name()) << endl // << "to : " << string(typeid(TTo).name()) << endl; //#ifdef MACOS_PLATFORM // static auto const item_count = 5000; // static auto const iteration_count = 5; //# endif //#ifdef LINUX_PLATFORM // static auto const item_count = 5000; // static auto const iteration_count = 5; //# endif //#ifdef FREEBSD_PLATFORM // static auto const item_count = 5000; // static auto const iteration_count = 5; //# endif //#ifdef WINDOWS_PLATFORM // static auto const item_count = 100000; // static auto const iteration_count = 10; //# endif // vector<TFrom> from; // for (int i = 0; i < item_count; i++) { // TFrom const f = makeTestValue<TFrom>(i); // from.push_back(f); // } // int64_t time_convert = 0; // { // vector<TTo> to(item_count); // auto begin = high_resolution_clock::now(); // for (size_t n = 0; n < iteration_count; n++) // for (size_t i = 0; i < item_count; i++) // to[i] = convert<TTo>(static_cast<TFrom>(from[i])); // auto end = high_resolution_clock::now(); // time_convert = duration_cast<nanoseconds>(end - begin).count(); // } // int64_t time_cached_convert = 0; // { // vector<TTo> to(item_count); // auto begin = high_resolution_clock::now(); // auto convertCached = std::bind( // iridium::caching::LazyCacher<TTo, TFrom>::cacheFunc, // convert<TTo, TFrom>, // std::placeholders::_1); // for (size_t n = 0; n < iteration_count; n++) // for (size_t i = 0; i < item_count; i++) // to[i] = convertCached(static_cast<TFrom>(from[i])); // auto end = high_resolution_clock::now(); // time_cached_convert = duration_cast<nanoseconds>(end - begin).count(); // } // cout << "convert time: " << time_convert << " ns" << endl; // cout << "convert cached time: " << time_cached_convert << " ns" << endl; // cout << "convert vs cached convert: " << (time_convert * 100 / time_cached_convert) << " %" << endl; // cout << endl; //} //TEST(benchmark) { // runBenchmark<int , string>(); // runBenchmark<double , string>(); // runBenchmark<string , int>(); // runBenchmark<string , double>(); //} TEST(specializations) { convert<std::string, std::chrono::system_clock::time_point, true>({}); convert<std::string, std::chrono::system_clock::duration, true>(std::chrono::system_clock::duration::zero()); convert<std::string, bool, true>({}); convert<std::string, int64_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, int64_t, true>({}); convert<std::string, uint64_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, uint64_t, true>({}); convert<std::string, int32_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, int32_t, true>({}); convert<std::string, uint32_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, uint32_t, true>({}); convert<std::string, int16_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, int16_t, true>({}); convert<std::string, uint16_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, uint16_t, true>({}); convert<std::string, int8_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, int8_t, true>({}); convert<std::string, uint8_t, uint8_t, true>({}, uint8_t{10}); convert<std::string, uint8_t, true>({}); convert<std::string, double, uint8_t, true>({}, uint8_t{10}); convert<std::string, double, true>({}); convert<std::string, float, uint8_t, true>({}, uint8_t{10}); convert<std::string, float, true>({}); convert<std::string, std::thread::id, true>({}); convert<std::string, std::exception, true>({}); convert<std::chrono::system_clock::time_point, std::string, true>("2025-12-12 01:01:01.001"); convert<bool, std::string, true>("true"); convert<int32_t, std::string, true>("0"); convert<int64_t, std::string, true>("0"); convert<uint32_t, std::string, true>("0"); convert<uint16_t, std::string, true>("0"); convert<uint8_t, std::string, true>("0"); convert<uint64_t, std::string, true>("0"); convert<double, std::string, true>("0"); convert<float, std::string, true>("0"); convert<std::string, long long, true>({}); convert<std::string, std::wstring, true>({}); convert<std::wstring, std::string, true>({}); convert<std::string, std::u16string, true>({}); convert<std::string, std::u32string, true>({}); convert<std::u16string, std::string, true>({}); convert<std::u32string, std::string, true>({}); convert<int, int, true>({}); convert<std::string, std::string, true>({}); #if __cplusplus < 202302L convert<std::string, std::nested_exception, true>({}); #endif convert<std::string, uintptr_t, true>({}); convert<std::string, intptr_t, true>({}); convert<std::string, std::unordered_map<string, int>, true >( { {"s1", 1}, {"s2", 2} } ); convert<std::string, std::map<string, int>, true >( { {"s1", 1}, {"s2", 2} } ); convert<std::string, std::vector<string>, true >( { "s1", "s2" } ); convert<std::string, std::list<string>, true >( { "s1", "s2" } ); convert<std::string, std::set<string>, true >( { "s1", "s2" } ); convert<std::string, std::pair<string, int>, true >( { "s1", 1 } ); } TEST(types) { ASSERT("true" , equal, convert<string>(true)); ASSERT("false" , equal, convert<string>(false)); ASSERT("12345" , equal, convert<string>(uint64_t{12345})); ASSERT("5" , equal, convert<string>(uint64_t{5})); ASSERT("5" , equal, convert<string>(uint32_t{5})); ASSERT("-5" , equal, convert<string>(int64_t{-5})); ASSERT("-5" , equal, convert<string>(int32_t{-5})); ASSERT("0" , equal, convert<string>(int64_t{0})); ASSERT("0" , equal, convert<string>(int32_t{0})); ASSERT("F" , equal, convert<string>(15, uint8_t{16})); ASSERT("5.50000", equal, convert<string>(5.5)); ASSERT("5.56" , equal, convert<string>(5.556, static_cast<uint8_t>(2))); ASSERT("5.55" , equal, convert<string>(5.554, static_cast<uint8_t>(2))); ASSERT("625.10" , equal, convert<string>(625.1, static_cast<uint8_t>(2))); ASSERT("-5.50000",equal, convert<string>(-5.5)); ASSERT("-5.56" , equal, convert<string>(-5.556, static_cast<uint8_t>(2))); ASSERT("-5.55" , equal, convert<string>(-5.554, static_cast<uint8_t>(2))); ASSERT( "17976931348623157", equal, convert<string>( std::numeric_limits<double>::max()).substr(0, 17)); ASSERT("-17976931348623157", equal, convert<string>(-std::numeric_limits<double>::max()).substr(0, 18)); ASSERT(true , equal, convert<bool>(string("True"))); ASSERT(false , equal, convert<bool>(string("false"))); ASSERT(convert<bool>(string("wrong true")), std::exception); ASSERT(convert<bool>(string("")) , std::exception); ASSERT(0 , equal, convert<int32_t>(string("0"))); ASSERT(5 , equal, convert<int32_t>(string("5"))); ASSERT(-5 , equal, convert<int32_t>(string("-5"))); ASSERT(convert<int32_t>(string("5 wrong")), std::exception); ASSERT(convert<int32_t>(string("")) , std::exception); // double ASSERT(5.5 , equal, convert<double>(string("5.5"))); ASSERT(-5.5 , equal, convert<double>(string("-5.5"))); ASSERT(static_cast<double>(525.1), equal, convert<double>(string("525.1"))); ASSERT(convert<double>(string("5.5 wrong")) , std::exception); ASSERT(convert<double>(string("")) , std::exception); // float ASSERT(5.5 , equal, convert<float>(string("5.5"))); ASSERT(-5.5 , equal, convert<float>(string("-5.5"))); ASSERT(static_cast<float>(525.1), equal, convert<float>(string("525.1"))); ASSERT(convert<float>(string("5.5 wrong")) , std::exception); ASSERT(convert<float>(string("")) , std::exception); // time_point typedef system_clock::time_point TTimePoint; using std::chrono::seconds; auto to_time_t = [] (TTimePoint const &t) { return time_t(std::chrono::duration_cast<std::chrono::seconds>(t.time_since_epoch()).count()); }; ASSERT("2015-05-05 05:05:05.000", equal, convert<string>(TTimePoint(seconds(1430802305)))); ASSERT(to_time_t(convert<TTimePoint>(string("2015-05-05 05:05:05.000"))), equal, 1430802305); ASSERT(TTimePoint(std::chrono::milliseconds(555)), equal, convert<TTimePoint>(string("1970-01-01 00:00:00.555"))); #ifdef PLATFORM_CPU64 ASSERT(4449517261, equal, to_time_t(convert<TTimePoint>(string("2111-01-01 01:01:01.000")))); #endif ASSERT(convert<TTimePoint>(string("2015-05-05 05:05:05.000 wrong")), std::exception); { system_clock::duration d = std::chrono::hours(1) + std::chrono::minutes(2) + std::chrono::seconds(3) + std::chrono::milliseconds(4) + std::chrono::microseconds(5); // std::chrono::nanoseconds(6); std::string s = "1h2m3s4ms5us"; ASSERT(s, equal, convert<string>(d)); ASSERT(d, equal, convert<system_clock::duration>(s)); ASSERT(std::chrono::seconds(5), equal, convert<system_clock::duration>(string("5"))); } #if __cplusplus < 202302L ASSERT(std::string(u8"ħëłlö"), equal, convert<string>(std::wstring(L"ħëłlö"))); #else ASSERT(std::string("ħëłlö"), equal, convert<string>(std::wstring(L"ħëłlö"))); #endif ASSERT(convert<string>(0, uint8_t(0)), std::exception); } enum TEnumTest { E1, E2, E3 = 5, E4 = AE1, E5 }; TEST(enum_) { { // TEnum e = 42; } ASSERT(TEnum::E1, equal, static_cast<int>(TEnumTest::E1)); ASSERT(TEnum::E2, equal, static_cast<int>(TEnumTest::E2)); ASSERT(TEnum::E3, equal, static_cast<int>(TEnumTest::E3)); ASSERT(TEnum::E4, equal, static_cast<int>(TEnumTest::E4)); ASSERT(TEnum::E5, equal, static_cast<int>(TEnumTest::E5)); ASSERT(static_cast<int>(TEnumTest::E1), equal, static_cast<int>(convert<TEnum>(string("E1")))); ASSERT(static_cast<int>(TEnumTest::E2), equal, static_cast<int>(convert<TEnum>(string("E2")))); ASSERT(static_cast<int>(TEnumTest::E3), equal, static_cast<int>(convert<TEnum>(string("E3")))); ASSERT(static_cast<int>(TEnumTest::E4), equal, static_cast<int>(convert<TEnum>(string("E4")))); ASSERT(static_cast<int>(TEnumTest::E5), equal, static_cast<int>(convert<TEnum>(string("E5")))); ASSERT("E1", equal, convert<string>(TEnum::E1)); ASSERT("E2", equal, convert<string>(TEnum::E2)); ASSERT("E3", equal, convert<string>(TEnum::E3)); ASSERT("E4", equal, convert<string>(TEnum::E4)); ASSERT("E5", equal, convert<string>(TEnum::E5)); { TEnum e = TEnum::E1; ASSERT("E1", equal, convert<string>(e)); } { TEnum e = static_cast<TEnum::TEnumInternal>(1); ASSERT("E2", equal, convert<string>(e)); } // LOGI << "'" << convert<TEnum>(string("E55")) << "'"; ASSERT(convert<TEnum>(string("E55")), std::runtime_error); ASSERT("UNKNOWN", equal, convert<string>(TEnum(static_cast<TEnum::TEnumInternal>(10)))); std::list<TEnum::TEnumInternal> l; for (auto const &i: TEnum::getEnums()) l.push_back(i); ASSERT(std::list<TEnum::TEnumInternal>( { TEnum::E1, TEnum::E2, TEnum::E3, TEnum::E4, TEnum::E5 } ), equal, l); } TEST(strings) { ASSERT("''1''2''3''", equal, replace("'1'2'3'", "'", "''")); ASSERT(".1.2.3.", equal, replace("0102030", "0", ".")); ASSERT(".1.2.3.", equal, replace("00100200300", "00", ".")); } #if __cplusplus < 202302L void innerFunction() { throw std::runtime_error("Inner exception"); } void middleFunction() { try { innerFunction(); } catch (...) { std::throw_with_nested(std::runtime_error("Middle exception")); } } void outerFunction() { try { middleFunction(); } catch (...) { std::throw_with_nested(std::runtime_error("Outer exception")); } } TEST(exception) { try { outerFunction(); } catch (const std::exception &e) { ASSERT("Outer exception: Middle exception: Inner exception", equal, convert<string>(e)); } } #endif } // namespace iridium::convertion