diff --git a/.github/workflows/linux-cxx20-vcpkg.yaml b/.github/workflows/linux-cxx20-vcpkg.yaml index e51347c8..72f63580 100644 --- a/.github/workflows/linux-cxx20-vcpkg.yaml +++ b/.github/workflows/linux-cxx20-vcpkg.yaml @@ -1,9 +1,9 @@ -name: linux-cxx20-vcpkg +name: linux-cxx20-vcpkg on: [push, pull_request] -env: +env: VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" jobs: @@ -30,7 +30,7 @@ jobs: db: postgres - compiler: llvm compiler-version: 16 - db: sqlite + db: sqlite - compiler: llvm compiler-version: 18 db: sqlite @@ -46,7 +46,7 @@ jobs: db: sqlite - compiler: llvm compiler-version: 16 - db: mysql + db: mysql - compiler: llvm compiler-version: 18 db: mysql @@ -80,7 +80,7 @@ jobs: concurrency: group: ci-${{ github.ref }}-${{ github.job }}-${{ matrix.compiler }}-${{ matrix.compiler-version }}-${{ matrix.db }} cancel-in-progress: true - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 @@ -105,7 +105,7 @@ jobs: sudo apt update sudo apt install -y ninja-build ${{ matrix.additional-dep }} - name: Compile - if: matrix.db == 'postgres' + if: matrix.db == 'postgres' run: | if [[ "${{ matrix.compiler }}" == "llvm" ]]; then export CC=clang-${{ matrix.compiler-version }} @@ -117,10 +117,10 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF cmake --build build - name: Compile - if: matrix.db == 'duckdb' + if: matrix.db == 'duckdb' run: | if [[ "${{ matrix.compiler }}" == "llvm" ]]; then export CC=clang-${{ matrix.compiler-version }} @@ -135,7 +135,7 @@ jobs: cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_DUCKDB=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF cmake --build build - name: Compile - if: matrix.db == 'sqlite' + if: matrix.db == 'sqlite' run: | if [[ "${{ matrix.compiler }}" == "llvm" ]]; then export CC=clang-${{ matrix.compiler-version }} @@ -147,10 +147,10 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_CHECK_HEADERS=ON + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_CHECK_HEADERS=ON cmake --build build - name: Compile - if: matrix.db == 'mysql' + if: matrix.db == 'mysql' run: | if [[ "${{ matrix.compiler }}" == "llvm" ]]; then export CC=clang-${{ matrix.compiler-version }} @@ -162,14 +162,14 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-linux-dynamic + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-linux-dynamic cmake --build build - name: Set up postgres - if: matrix.db == 'postgres' + if: matrix.db == 'postgres' run: | sudo systemctl start postgresql.service sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'password';" - - name: Set up mysql + - name: Set up mysql if: matrix.db == 'mysql' run: | sudo systemctl start mysql diff --git a/include/sqlgen/internal/from_str_vec.hpp b/include/sqlgen/internal/from_str_vec.hpp index f919ef95..b747fbab 100644 --- a/include/sqlgen/internal/from_str_vec.hpp +++ b/include/sqlgen/internal/from_str_vec.hpp @@ -14,6 +14,7 @@ #include "../Result.hpp" #include "../parsing/Parser.hpp" #include "call_destructors_where_necessary.hpp" +#include "ptr_cast.hpp" namespace sqlgen::internal { @@ -72,7 +73,7 @@ template Result from_str_vec( const std::vector>& _str_vec) { alignas(T) unsigned char buf[sizeof(T)]{}; - auto ptr = rfl::internal::ptr_cast(&buf); + auto ptr = ptr_cast(&buf); auto view = rfl::to_view(*ptr); const auto [err, num_fields_assigned] = read_into_view(_str_vec, &view); if (err) [[unlikely]] { diff --git a/include/sqlgen/internal/get_type_name.hpp b/include/sqlgen/internal/get_type_name.hpp new file mode 100644 index 00000000..64b281f4 --- /dev/null +++ b/include/sqlgen/internal/get_type_name.hpp @@ -0,0 +1,48 @@ +#ifndef SQLGEN_INTERNAL_GET_TYPE_NAME_HPP_ +#define SQLGEN_INTERNAL_GET_TYPE_NAME_HPP_ + +#include + +#if __has_include() +#include +#endif + +namespace sqlgen::internal { + +template +consteval auto get_type_name_str_view() { +#if __cpp_lib_source_location >= 201907L + const auto func_name = + std::string_view{std::source_location::current().function_name()}; +#elif defined(_MSC_VER) + // Officially, we only support MSVC versions that are modern enough to contain + // , but inofficially, this might work. + const auto func_name = std::string_view{__FUNCSIG__}; +#else + const auto func_name = std::string_view{__PRETTY_FUNCTION__}; +#endif +#if defined(__clang__) + const auto split = func_name.substr(0, func_name.size() - 1); + return split.substr(split.find("T = ") + 4); +#elif defined(__GNUC__) + const auto split = func_name.substr(0, func_name.size() - 1); + return split.substr(split.find("T = ") + 4); +#elif defined(_MSC_VER) + auto split = func_name.substr(0, func_name.size() - 7); + split = split.substr(split.find("get_type_name_str_view<") + 23); + auto pos = split.find(" "); + if (pos != std::string_view::npos) { + return split.substr(pos + 1); + } + return split; +#else + static_assert( + false, + "You are using an unsupported compiler. Please use GCC, Clang " + "or MSVC."); +#endif +} + +} // namespace sqlgen::internal + +#endif diff --git a/include/sqlgen/internal/ptr_cast.hpp b/include/sqlgen/internal/ptr_cast.hpp new file mode 100644 index 00000000..782d43bf --- /dev/null +++ b/include/sqlgen/internal/ptr_cast.hpp @@ -0,0 +1,22 @@ +#ifndef SQLGEN_INTERNAL_PTR_CAST_HPP_ +#define SQLGEN_INTERNAL_PTR_CAST_HPP_ + +namespace sqlgen::internal { + +/// Normally, we would use std::launder(reinterpret_cast<...>(...)), +/// but there are weird issues on GCC 12 under certain compiler settings, +/// so we are using this workaround instead. + +template +inline T1 ptr_cast(T2* _ptr) { + return static_cast(static_cast(_ptr)); +} + +template +inline T1 ptr_cast(const T2* _ptr) { + return static_cast(static_cast(_ptr)); +} + +} // namespace sqlgen::internal + +#endif diff --git a/include/sqlgen/parsing/Parser_default.hpp b/include/sqlgen/parsing/Parser_default.hpp index ec29ddf2..9a072ec8 100644 --- a/include/sqlgen/parsing/Parser_default.hpp +++ b/include/sqlgen/parsing/Parser_default.hpp @@ -9,6 +9,7 @@ #include "../Result.hpp" #include "../dynamic/Type.hpp" #include "../dynamic/types.hpp" +#include "../internal/get_type_name.hpp" #include "../transpilation/has_reflection_method.hpp" #include "Parser_base.hpp" @@ -135,7 +136,7 @@ struct Parser { for (std::size_t i = 0; i < std::size(values); ++i) { enum_names[i] = values[i].first; } - constexpr auto org_name = rfl::internal::get_type_name_str_view(); + constexpr auto org_name = internal::get_type_name_str_view(); static_assert(org_name.size() < 64, "Enum type exceeds type level. If it's defined in a nested " "namespace, consider moving it up to a higher level.");