Compare commits
31 Commits
Developmen
...
f322ce3655
| Author | SHA1 | Date | |
|---|---|---|---|
| f322ce3655 | |||
| b769357bd0 | |||
| ea53392645 | |||
| 0977669bd5 | |||
| 1328b17b47 | |||
| 29491b8c3e | |||
| 589bc61c6e | |||
| a0d43a31e9 | |||
| 122d4652a6 | |||
| 09c27d5242 | |||
| c00fee259f | |||
| 6b8e73edc4 | |||
| 8b3d9818c8 | |||
| 30b3665721 | |||
| a682d8ade2 | |||
| 56418bb401 | |||
| d67c041df1 | |||
| d04876b18b | |||
| c3b006c281 | |||
| 64bbcdd64a | |||
| 19e53feccd | |||
| 842ff8963c | |||
| cec23c8c02 | |||
| f780e6f59a | |||
| 934b44c1f8 | |||
| 7c0f086969 | |||
| 56e558e830 | |||
| 8fe1281cb7 | |||
| 9f32d230d5 | |||
| 23a3b4b904 | |||
| 529f053e60 |
@@ -18,7 +18,9 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
build_type: ["Debug", "RelWithDebInfo", "Release"]
|
build_type: ["Debug", "RelWithDebInfo", "Release"]
|
||||||
name: "Build & Test ${{ matrix.build_type }}"
|
unity_build: ["ON", "OFF"]
|
||||||
|
conan_profile: ["./ConanProfiles/clang", "./ConanProfiles/clangd", "./ConanProfiles/clangd_asan"]
|
||||||
|
name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }})"
|
||||||
steps:
|
steps:
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
run: apt-get update && apt-get install -y nodejs
|
run: apt-get update && apt-get install -y nodejs
|
||||||
@@ -28,19 +30,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Show ccache stats before
|
|
||||||
run: ccache --zero-stats
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
conan profile detect
|
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=${{ matrix.conan_profile }} --build=missing -s build_type=${{ matrix.build_type }}
|
||||||
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages --build=missing -s build_type=${{ matrix.build_type }} -o bin2cpp/*:build_tests=True
|
cmake -S . -B ./build/${{ matrix.build_type }} --toolchain ./build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja"
|
||||||
cmake -S . -B ./build/${{ matrix.build_type }} --toolchain ./build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -G "Ninja"
|
|
||||||
cmake --build build/${{ matrix.build_type }} --parallel $(nproc)
|
cmake --build build/${{ matrix.build_type }} --parallel $(nproc)
|
||||||
|
|
||||||
- name: Show ccache stats after
|
|
||||||
run: ccache --show-stats
|
|
||||||
|
|
||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: |
|
run: |
|
||||||
cd ./build/${{ matrix.build_type }}
|
cd ./build/${{ matrix.build_type }}
|
||||||
|
|||||||
55
.gitea/workflows/package.yml
Normal file
55
.gitea/workflows/package.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
name: Conan Packaging
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
conan-packages:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 120
|
||||||
|
container:
|
||||||
|
image: git.romainboullard.com/bigfootdev/linuxcppbuilder:main
|
||||||
|
env:
|
||||||
|
ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }}
|
||||||
|
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||||
|
name: "Package Bin2CPP/1.0.0"
|
||||||
|
steps:
|
||||||
|
- name: Set BRANCH_NAME
|
||||||
|
run: echo "BRANCH_NAME=$(echo $GITHUB_REF_NAME | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
run: apt-get update && apt-get install -y nodejs
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Show ccache stats before
|
||||||
|
run: ccache --zero-stats
|
||||||
|
|
||||||
|
- name: Run Conan packaging
|
||||||
|
run: |
|
||||||
|
echo "Building Bin2CPP@$1.0.0"
|
||||||
|
CONAN_LOGIN_USERNAME=${ARTIFACTORY_USER} \
|
||||||
|
CONAN_PASSWORD=${ARTIFACTORY_PASSWORD} \
|
||||||
|
conan create . \
|
||||||
|
--version=1.0.0 \
|
||||||
|
--user=bigfootdev \
|
||||||
|
--channel=${{ env.BRANCH_NAME }} \
|
||||||
|
-pr:b=./ConanProfiles/clang -pr:h=./ConanProfiles/clang \
|
||||||
|
--build=missing --remote=bigfootpackages
|
||||||
|
|
||||||
|
CONAN_LOGIN_USERNAME=${ARTIFACTORY_USER} \
|
||||||
|
CONAN_PASSWORD=${ARTIFACTORY_PASSWORD} \
|
||||||
|
conan upload bin2cpp/1.0.0@bigfootdev/${{ env.BRANCH_NAME }} \
|
||||||
|
--only-recipe --remote=bigfootpackages
|
||||||
|
|
||||||
|
- name: Show ccache stats after
|
||||||
|
run: ccache --show-stats
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Generate
|
- name: Generate
|
||||||
run: |
|
run: |
|
||||||
conan profile detect
|
conan profile detect
|
||||||
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages --build=missing -s build_type=Debug -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=./ConanProfiles/clang_coverage -pr:b=./ConanProfiles/clang_coverage --build=missing -s build_type=Debug
|
||||||
cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja"
|
cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja"
|
||||||
cmake --build build/Debug --parallel $(nproc)
|
cmake --build build/Debug --parallel $(nproc)
|
||||||
|
|
||||||
|
|||||||
56
Bin2CPP/Sources/Bin2CPP/CMakeLists.txt
Normal file
56
Bin2CPP/Sources/Bin2CPP/CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||||
|
project(${PackageName})
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME})
|
||||||
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE BIN2CPPEXE_SOURCES
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE BIN2CPPEXE_HEADERS
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
${BIN2CPPEXE_SOURCES}
|
||||||
|
PRIVATE
|
||||||
|
FILE_SET HEADERS
|
||||||
|
BASE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||||
|
FILES
|
||||||
|
${BIN2CPPEXE_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Bin2CPPCompileAndLinkFlags
|
||||||
|
Bin2CPPLib
|
||||||
|
CLI11::CLI11
|
||||||
|
${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
|
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${BIN2CPPEXE_SOURCES} ${BIN2CPPEXE_HEADERS})
|
||||||
|
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder})
|
||||||
|
|
||||||
|
##################ASAN SETUP###################
|
||||||
|
|
||||||
|
if(${ASAN})
|
||||||
|
if (MSVC)
|
||||||
|
get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
||||||
|
set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll")
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Copying ASan DLL: ${ASAN_DLL} to $<TARGET_FILE_DIR:${PROJECT_NAME}>"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
########INSTALL
|
||||||
|
|
||||||
|
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
68
Bin2CPP/Sources/Bin2CPP/main.cpp
Normal file
68
Bin2CPP/Sources/Bin2CPP/main.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <Generator.hpp>
|
||||||
|
#include <Log.hpp>
|
||||||
|
|
||||||
|
#include <CLI/CLI.hpp>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
CLI::App app {"Bin2CPP allows you to generate a C++ header containing the binary content of an input file"};
|
||||||
|
argv = app.ensure_utf8(argv);
|
||||||
|
|
||||||
|
std::string input;
|
||||||
|
app.add_option("-f,--input", input, "The input file")->required();
|
||||||
|
std::string output;
|
||||||
|
app.add_option("-o,--output", output, "The output file")->required();
|
||||||
|
std::optional<std::string> arrayType;
|
||||||
|
app.add_option("--arrayType", arrayType, "The type of the array");
|
||||||
|
std::optional<std::string> arrayInclude;
|
||||||
|
app.add_option("--arrayInclude", arrayInclude, "Include for the array type");
|
||||||
|
std::optional<std::string> arrayName;
|
||||||
|
app.add_option("--arrayName", arrayName, "The array name");
|
||||||
|
std::optional<std::string> customNamespace;
|
||||||
|
app.add_option("--namespace", customNamespace, "The namespace");
|
||||||
|
bool verbose = false;
|
||||||
|
app.add_option("--verbose", verbose, "Activate logging");
|
||||||
|
|
||||||
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
|
std::unique_ptr<Bin2CPP::Singleton<Bin2CPP::Log>::Lifetime> loggerLifetime =
|
||||||
|
verbose ? std::make_unique<Bin2CPP::Singleton<Bin2CPP::Log>::Lifetime>() : nullptr;
|
||||||
|
|
||||||
|
Bin2CPP::Generator generator(input);
|
||||||
|
if (arrayType)
|
||||||
|
{
|
||||||
|
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE, arrayType.value());
|
||||||
|
}
|
||||||
|
if (arrayInclude)
|
||||||
|
{
|
||||||
|
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE_INCLUDE, arrayInclude.value());
|
||||||
|
}
|
||||||
|
if (arrayName)
|
||||||
|
{
|
||||||
|
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_NAME, arrayName.value());
|
||||||
|
}
|
||||||
|
if (customNamespace)
|
||||||
|
{
|
||||||
|
generator.SetMapping(Bin2CPP::MappingKey::NAMESPACE, customNamespace.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!generator.Generate())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to generate '{}'", input);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream out(output);
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to open '{}'", output);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << generator.Get();
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
BIN2CPP_LOG_INFO("'{}' Generated !", output);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|
||||||
project(${PackageName})
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME})
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
|
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include)
|
|
||||||
|
|
||||||
# collect sources (reconfigure when files are added/removed)
|
|
||||||
file(GLOB_RECURSE SOURCES
|
|
||||||
CONFIGURE_DEPENDS
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
|
||||||
PRIVATE
|
|
||||||
${SOURCES}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC CLI11::CLI11 Bin2CPPLib)
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS})
|
|
||||||
|
|
||||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${SOURCES})
|
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder})
|
|
||||||
|
|
||||||
bin2cpp_setup_dependencies("Bin2CPPExe")
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -2,27 +2,51 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|||||||
project(${PackageName})
|
project(${PackageName})
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC)
|
add_library(${PROJECT_NAME} STATIC)
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include)
|
file(GLOB_RECURSE BIN2CPPLIB_SOURCES
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
# collect sources (reconfigure when files are added/removed)
|
file(GLOB_RECURSE BIN2CPPLIB_HEADERS
|
||||||
file(GLOB_RECURSE SOURCES
|
|
||||||
CONFIGURE_DEPENDS
|
CONFIGURE_DEPENDS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE BIN2CPPLIB_OTHERS
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp.in
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
target_sources(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${SOURCES}
|
${BIN2CPPLIB_SOURCES}
|
||||||
|
PUBLIC
|
||||||
|
FILE_SET HEADERS
|
||||||
|
BASE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||||
|
FILES
|
||||||
|
${BIN2CPPLIB_HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC EASTL::EASTL rapidhash::rapidhash mimalloc)
|
target_link_libraries(${PROJECT_NAME}
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS})
|
PRIVATE
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace> quill::quill)
|
Bin2CPPCompileAndLinkFlags
|
||||||
|
PUBLIC
|
||||||
|
$<IF:$<BOOL:${ASAN}>,mimalloc-asan,mimalloc-static>
|
||||||
|
quill::quill
|
||||||
|
$<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace>
|
||||||
|
magic_enum::magic_enum)
|
||||||
|
|
||||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${SOURCES})
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
|
PUBLIC
|
||||||
|
QUILL_NO_EXCEPTIONS
|
||||||
|
QUILL_DISABLE_NON_PREFIXED_MACROS)
|
||||||
|
|
||||||
|
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/MimallocImpl.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||||
|
|
||||||
|
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${BIN2CPPLIB_SOURCES} ${BIN2CPPLIB_HEADERS} ${BIN2CPPLIB_OTHERS})
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder})
|
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder})
|
||||||
280
Bin2CPP/Sources/Bin2CPPLib/Generator.cpp
Normal file
280
Bin2CPP/Sources/Bin2CPPLib/Generator.cpp
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Generator.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Generator.hpp>
|
||||||
|
|
||||||
|
#include <Assert.hpp>
|
||||||
|
#include <GeneratedTemplate.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <regex>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
Generator::Generator(const std::string_view p_inputFile):
|
||||||
|
m_inputFile(p_inputFile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void Generator::SetMapping(const MappingKey p_key, const std::string_view p_value)
|
||||||
|
{
|
||||||
|
const std::optional<std::size_t> index = magic_enum::enum_index(p_key);
|
||||||
|
BIN2CPP_CRITICAL_ASSERT(index.has_value(), "Incorrect mapping key! Got {}", magic_enum::enum_integer(p_key));
|
||||||
|
|
||||||
|
m_mappingTable[index.value()] = p_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::Generate()
|
||||||
|
{
|
||||||
|
if (!ComputeMappings())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Invalid mappings! Can't generate file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_result = g_generatedTemplate;
|
||||||
|
|
||||||
|
for (std::uint32_t i = 0; i < m_mappingTable.size(); ++i)
|
||||||
|
{
|
||||||
|
const std::string KEY = magic_enum::enum_name(magic_enum::enum_value<MappingKey>(i)).data();
|
||||||
|
const std::string& VALUE = m_mappingTable[i];
|
||||||
|
|
||||||
|
const std::string pattern = "\\{\\{" + KEY + "\\}\\}";
|
||||||
|
std::regex placeholderRegex(pattern);
|
||||||
|
m_result = std::regex_replace(m_result, placeholderRegex, VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
std::string_view Generator::Get() const
|
||||||
|
{
|
||||||
|
return m_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeMappings()
|
||||||
|
{
|
||||||
|
std::filesystem::path file {m_inputFile.data()};
|
||||||
|
if (!std::filesystem::exists(file))
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("File '{}' does not exists!", m_inputFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (std::filesystem::is_directory(file))
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("'{}' is not a file!", m_inputFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ComputeFilename())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute filename");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ComputeGuardName())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute GuardName");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ComputeArrayTypeInclude())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute ArrayTypeInclude");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ComputeArrayType())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute ArrayType");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ComputeArrayName())
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute ArrayName");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream in {m_inputFile.data(), std::ios::binary};
|
||||||
|
if (!in)
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to open '{}'", m_inputFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in.seekg(0, std::ios::end);
|
||||||
|
const size_t fileSize = static_cast<size_t>(in.tellg());
|
||||||
|
in.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
std::vector<std::byte> data(fileSize);
|
||||||
|
in.read(std::bit_cast<char*>(data.data()), fileSize);
|
||||||
|
|
||||||
|
if (!ComputeArraySize(data))
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute ArraySize");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ComputeData(data))
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Failed to compute Data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeFilename()
|
||||||
|
{
|
||||||
|
std::filesystem::path file {m_inputFile.data()};
|
||||||
|
m_mappingTable[magic_enum::enum_index(MappingKey::FILENAME).value()] = file.filename().string().c_str();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeGuardName()
|
||||||
|
{
|
||||||
|
std::filesystem::path file {m_inputFile.data()};
|
||||||
|
std::string guardName = file.filename().string();
|
||||||
|
|
||||||
|
std::transform(guardName.begin(),
|
||||||
|
guardName.end(),
|
||||||
|
guardName.begin(),
|
||||||
|
[](const char c)
|
||||||
|
{
|
||||||
|
if (!std::isalnum(c))
|
||||||
|
{
|
||||||
|
return static_cast<int>('_');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::toupper(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_mappingTable[magic_enum::enum_index(MappingKey::GUARD_NAME).value()] = std::format("{}_HPP", guardName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeArrayTypeInclude()
|
||||||
|
{
|
||||||
|
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE_INCLUDE).value()];
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
value = "<array>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeArrayType()
|
||||||
|
{
|
||||||
|
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE).value()];
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
value = "std::array";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeArrayName()
|
||||||
|
{
|
||||||
|
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_NAME).value()];
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
std::filesystem::path file {m_inputFile.data()};
|
||||||
|
value = std::format("g_{}", file.filename().string());
|
||||||
|
|
||||||
|
std::transform(value.begin(),
|
||||||
|
value.end(),
|
||||||
|
value.begin(),
|
||||||
|
[](const char c)
|
||||||
|
{
|
||||||
|
if (!std::isalnum(c))
|
||||||
|
{
|
||||||
|
return static_cast<int>('_');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return static_cast<int>(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeArraySize(const std::span<std::byte> p_data)
|
||||||
|
{
|
||||||
|
m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_SIZE).value()] = std::to_string(p_data.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::ComputeData(const std::span<std::byte> p_data)
|
||||||
|
{
|
||||||
|
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::DATA).value()];
|
||||||
|
value.clear();
|
||||||
|
|
||||||
|
constexpr std::size_t bytesPerLine = 16;
|
||||||
|
constexpr std::string_view linePrefix = "\n ";
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < p_data.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i > 0 && i % bytesPerLine == 0)
|
||||||
|
{
|
||||||
|
value.append(linePrefix.data(), linePrefix.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string element = std::format("std::byte{{0x{:02X}}}", std::to_integer<std::uint8_t>(p_data[i]));
|
||||||
|
value.append(element.data(), element.size());
|
||||||
|
|
||||||
|
if (i + 1 < p_data.size())
|
||||||
|
{
|
||||||
|
value.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool Generator::Validate()
|
||||||
|
{
|
||||||
|
std::regex unreplacedRegex(R"(\{\{[A-Z_]+\}\})");
|
||||||
|
std::smatch match;
|
||||||
|
|
||||||
|
if (std::regex_search(m_result, match, unreplacedRegex))
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_ERROR("Warning: Unreplaced placeholder found: {}", match.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace Bin2CPP
|
||||||
134
Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp
Normal file
134
Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Assert.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date October 2025
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIN2CPP_ASSERT_HPP
|
||||||
|
#define BIN2CPP_ASSERT_HPP
|
||||||
|
#include <Log.hpp>
|
||||||
|
|
||||||
|
#if defined BIN2CPP_NOT_OPTIMIZED
|
||||||
|
|
||||||
|
#include <cpptrace/cpptrace.hpp>
|
||||||
|
|
||||||
|
#include <source_location>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if defined BIN2CPP_LINUX
|
||||||
|
#include <csignal>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
class AssertHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssertHandler() = delete;
|
||||||
|
|
||||||
|
AssertHandler(const AssertHandler& p_handler) = delete;
|
||||||
|
AssertHandler(AssertHandler&& p_handler) = delete;
|
||||||
|
|
||||||
|
~AssertHandler() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an assertion.
|
||||||
|
*
|
||||||
|
* \param p_location Location of the assertion.
|
||||||
|
* \param p_stacktrace The stack trace
|
||||||
|
* \param p_format Format string for the assertion message.
|
||||||
|
* \param p_args Arguments for the format string.
|
||||||
|
*/
|
||||||
|
template<typename... ARGS>
|
||||||
|
static void Handle(const std::source_location& p_location,
|
||||||
|
const std::string_view p_stacktrace,
|
||||||
|
std::format_string<ARGS...> p_format,
|
||||||
|
ARGS&&... p_args)
|
||||||
|
{
|
||||||
|
BIN2CPP_LOG_FATAL("Assert: {} (File:{}, Line:{}, Function:{})\n{}",
|
||||||
|
std::format(p_format, std::forward<ARGS>(p_args)...),
|
||||||
|
p_location.file_name(),
|
||||||
|
p_location.line(),
|
||||||
|
p_location.function_name(),
|
||||||
|
p_stacktrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertHandler& operator=(const AssertHandler& p_handler) = delete;
|
||||||
|
AssertHandler& operator=(AssertHandler&& p_handler) = delete;
|
||||||
|
};
|
||||||
|
} // namespace Bin2CPP
|
||||||
|
|
||||||
|
#if defined BIN2CPP_WINDOWS
|
||||||
|
#define BIN2CPP_BREAK \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
__debugbreak(); \
|
||||||
|
} while (false)
|
||||||
|
#elif defined BIN2CPP_LINUX
|
||||||
|
#define BIN2CPP_BREAK \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
std::raise(SIGTRAP); \
|
||||||
|
} while (false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BIN2CPP_ASSERT(p_assert, p_message, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
constexpr std::source_location location = std::source_location::current(); \
|
||||||
|
if (!(p_assert)) [[unlikely]] \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::AssertHandler::Handle(location, \
|
||||||
|
cpptrace::generate_trace().to_string(), \
|
||||||
|
p_message __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::Singleton<Bin2CPP::Log>::Instance().Flush(); \
|
||||||
|
} \
|
||||||
|
BIN2CPP_BREAK; \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
constexpr std::source_location location = std::source_location::current(); \
|
||||||
|
if (!(p_assert)) [[unlikely]] \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::AssertHandler::Handle(location, \
|
||||||
|
cpptrace::generate_trace().to_string(), \
|
||||||
|
p_message __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::Singleton<Bin2CPP::Log>::Instance().Flush(); \
|
||||||
|
} \
|
||||||
|
BIN2CPP_BREAK; \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
constexpr std::source_location location = std::source_location::current(); \
|
||||||
|
if (!(p_assert)) [[unlikely]] \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::AssertHandler::Handle(location, \
|
||||||
|
cpptrace::generate_trace().to_string(), \
|
||||||
|
p_message __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
Bin2CPP::Singleton<Bin2CPP::Log>::Instance().Flush(); \
|
||||||
|
} \
|
||||||
|
BIN2CPP_BREAK; \
|
||||||
|
std::abort(); \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define BIN2CPP_ASSERT(p_assert, p_message, ...)
|
||||||
|
|
||||||
|
#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...)
|
||||||
|
|
||||||
|
#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
36
Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp
Normal file
36
Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file GeneratedTemplate.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date March 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIN2CPP_GENERATED_TEMPLATE_HPP
|
||||||
|
#define BIN2CPP_GENERATED_TEMPLATE_HPP
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
constexpr std::string_view g_generatedTemplate = R"(/**
|
||||||
|
* Auto-generated header from: {{FILENAME}}
|
||||||
|
* Generated by Bin2CPP
|
||||||
|
*
|
||||||
|
* DO NOT TOUCH
|
||||||
|
*/
|
||||||
|
#ifndef {{GUARD_NAME}}
|
||||||
|
#define {{GUARD_NAME}}
|
||||||
|
#include {{ARRAY_TYPE_INCLUDE}}
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace {{NAMESPACE}}
|
||||||
|
{
|
||||||
|
inline constexpr {{ARRAY_TYPE}}<std::byte, {{ARRAY_SIZE}}> {{ARRAY_NAME}} = {
|
||||||
|
{{DATA}}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace {{NAMESPACE}}
|
||||||
|
|
||||||
|
#endif // {{GUARD_NAME}}
|
||||||
|
)";
|
||||||
|
} // namespace Bin2CPP
|
||||||
|
|
||||||
|
#endif
|
||||||
157
Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp
Normal file
157
Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Generator.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIN2CPP_GENERATOR_HPP
|
||||||
|
#define BIN2CPP_GENERATOR_HPP
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <span>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
enum class MappingKey
|
||||||
|
{
|
||||||
|
FILENAME,
|
||||||
|
GUARD_NAME,
|
||||||
|
NAMESPACE,
|
||||||
|
ARRAY_TYPE_INCLUDE,
|
||||||
|
ARRAY_TYPE,
|
||||||
|
ARRAY_SIZE,
|
||||||
|
ARRAY_NAME,
|
||||||
|
DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
class Generator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param p_inputFile the Input file
|
||||||
|
*/
|
||||||
|
Generator(const std::string_view p_inputFile);
|
||||||
|
|
||||||
|
Generator(const Generator& p_generator) = default;
|
||||||
|
Generator(Generator&& p_generator) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mapping
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetMapping(const MappingKey p_key, const std::string_view p_value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate
|
||||||
|
*
|
||||||
|
* \return True if successful, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool Generate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
std::string_view Get() const;
|
||||||
|
|
||||||
|
~Generator() = default;
|
||||||
|
|
||||||
|
Generator& operator=(const Generator& p_generator) = default;
|
||||||
|
Generator& operator=(Generator&& p_generator) = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Compute the mappings
|
||||||
|
*
|
||||||
|
* \return True if all mappings have valid values, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeMappings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the filename mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeFilename();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the guardName mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeGuardName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the arrayTypeInclude mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeArrayTypeInclude();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the arrayType mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeArrayType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the arrayName mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeArrayName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the arraySize mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeArraySize(const std::span<std::byte> p_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the data mapping
|
||||||
|
*
|
||||||
|
* \return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool ComputeData(const std::span<std::byte> p_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate generated is correct (no remaining tags)
|
||||||
|
*
|
||||||
|
* \return True if valid, false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool Validate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mapping table
|
||||||
|
*/
|
||||||
|
std::array<std::string, magic_enum::enum_count<MappingKey>()> m_mappingTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The input file
|
||||||
|
*/
|
||||||
|
std::string m_inputFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result
|
||||||
|
*/
|
||||||
|
std::string m_result;
|
||||||
|
};
|
||||||
|
} // namespace Bin2CPP
|
||||||
|
#endif
|
||||||
127
Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp
Normal file
127
Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Log.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIN2CPP_LOG_HPP
|
||||||
|
#define BIN2CPP_LOG_HPP
|
||||||
|
#include <Singleton.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#ifdef BIN2CPP_WINDOWS
|
||||||
|
#pragma warning(disable: 4702)
|
||||||
|
#endif
|
||||||
|
#include <quill/Backend.h>
|
||||||
|
#include <quill/Frontend.h>
|
||||||
|
#include <quill/LogMacros.h>
|
||||||
|
#include <quill/Logger.h>
|
||||||
|
#include <quill/sinks/ConsoleSink.h>
|
||||||
|
#if defined BIN2CPP_WINDOWS
|
||||||
|
#pragma warning(default: 4702)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Log();
|
||||||
|
|
||||||
|
Log(const Log& p_logger) = delete;
|
||||||
|
Log(Log&& p_logger) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a logger.
|
||||||
|
*
|
||||||
|
* \return The logger, nullptr if it does not exist
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
quill::Logger* GetLogger();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush all the loggers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Flush();
|
||||||
|
|
||||||
|
~Log();
|
||||||
|
|
||||||
|
Log& operator=(const Log& p_logger) = delete;
|
||||||
|
Log& operator=(Log&& p_logger) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* The sinks
|
||||||
|
*/
|
||||||
|
std::array<std::shared_ptr<quill::Sink>, 1> m_sinks;
|
||||||
|
};
|
||||||
|
} // namespace Bin2CPP
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_DEBUG(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_TRACE(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_INFO(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_WARN(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_ERROR(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BIN2CPP_LOG_FATAL(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (Bin2CPP::Singleton<Bin2CPP::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
if (quill::Logger* logger = Bin2CPP::Singleton<Bin2CPP::Log>::Instance().GetLogger()) \
|
||||||
|
{ \
|
||||||
|
QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
104
Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp
Normal file
104
Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Singleton.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIN2CPP_SINGLETON_HPP
|
||||||
|
#define BIN2CPP_SINGLETON_HPP
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
template<class TYPE>
|
||||||
|
class Singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Singleton() = delete;
|
||||||
|
|
||||||
|
Singleton(const Singleton& p_singleton) = delete;
|
||||||
|
Singleton(Singleton&& p_singleton) = delete;
|
||||||
|
|
||||||
|
~Singleton() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance.
|
||||||
|
*
|
||||||
|
* \return The instance
|
||||||
|
*/
|
||||||
|
static TYPE& Instance()
|
||||||
|
{
|
||||||
|
return ms_instance.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the instance initialized
|
||||||
|
*
|
||||||
|
* \return True if initialized, false otherwise
|
||||||
|
*/
|
||||||
|
static bool HasInstance()
|
||||||
|
{
|
||||||
|
return ms_instance.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Lifetime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* \param p_args Arguments for the singleton
|
||||||
|
*/
|
||||||
|
template<typename... ARGS>
|
||||||
|
explicit Lifetime(ARGS&&... p_args)
|
||||||
|
{
|
||||||
|
Initialize(std::forward<ARGS>(p_args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lifetime(const Lifetime& p_lifetime) = delete;
|
||||||
|
Lifetime(Lifetime&& p_lifetime) = delete;
|
||||||
|
|
||||||
|
~Lifetime()
|
||||||
|
{
|
||||||
|
Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
Lifetime& operator=(const Lifetime& p_lifetime) = delete;
|
||||||
|
[[nodiscard]]
|
||||||
|
Lifetime& operator=(Lifetime&& p_lifetime) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
Singleton& operator=(const Singleton& p_singleton) = delete;
|
||||||
|
[[nodiscard]]
|
||||||
|
Singleton& operator=(Singleton&& p_singleton) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Initialize the singleton.
|
||||||
|
*
|
||||||
|
* \param p_args Arguments for the singleton
|
||||||
|
*/
|
||||||
|
template<typename... ARGS>
|
||||||
|
static void Initialize(ARGS&&... p_args)
|
||||||
|
{
|
||||||
|
ms_instance.emplace(std::forward<ARGS>(p_args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize the singleton.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void Finalize()
|
||||||
|
{
|
||||||
|
ms_instance.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The singleton.
|
||||||
|
*/
|
||||||
|
inline static std::optional<TYPE> ms_instance;
|
||||||
|
};
|
||||||
|
} // namespace Bin2CPP
|
||||||
|
#endif
|
||||||
49
Bin2CPP/Sources/Bin2CPPLib/Log.cpp
Normal file
49
Bin2CPP/Sources/Bin2CPPLib/Log.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
* \file Log.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Log.hpp>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
Log::Log()
|
||||||
|
{
|
||||||
|
quill::Backend::start();
|
||||||
|
|
||||||
|
m_sinks[0] = quill::Frontend::create_or_get_sink<quill::ConsoleSink>("ConsoleSink");
|
||||||
|
|
||||||
|
quill::Logger* logger = quill::Frontend::create_or_get_logger("Bin2CPP", m_sinks[0]);
|
||||||
|
logger->set_log_level(quill::LogLevel::TraceL3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
quill::Logger* Log::GetLogger()
|
||||||
|
{
|
||||||
|
return quill::Frontend::get_logger("Bin2CPP");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void Log::Flush()
|
||||||
|
{
|
||||||
|
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
|
||||||
|
{
|
||||||
|
logger->flush_log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
Log::~Log()
|
||||||
|
{
|
||||||
|
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
|
||||||
|
{
|
||||||
|
quill::Frontend::remove_logger(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
quill::Backend::stop();
|
||||||
|
}
|
||||||
|
} // namespace Bin2CPP
|
||||||
96
Bin2CPP/Sources/Bin2CPPLib/MimallocImpl.cpp
Normal file
96
Bin2CPP/Sources/Bin2CPPLib/MimallocImpl.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file MimallocImpl.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#if defined BIN2CPP_WINDOWS
|
||||||
|
#pragma comment(linker, "/include:mi_version")
|
||||||
|
#pragma warning(disable: 4100 4559)
|
||||||
|
#elif defined BIN2CPP_LINUX
|
||||||
|
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#else
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Taken from mimalloc-new-delete.h
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This header provides convenient overrides for the new and
|
||||||
|
// delete operations in C++.
|
||||||
|
//
|
||||||
|
// This header should be included in only one source file!
|
||||||
|
//
|
||||||
|
// On Windows, or when linking dynamically with mimalloc, these
|
||||||
|
// can be more performant than the standard new-delete operations.
|
||||||
|
// See <https://en.cppreference.com/w/cpp/memory/new/operator_new>
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#include <new>
|
||||||
|
#include <mimalloc.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)
|
||||||
|
// stay consistent with VCRT definitions
|
||||||
|
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)
|
||||||
|
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)
|
||||||
|
#else
|
||||||
|
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict
|
||||||
|
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void operator delete(void* p) noexcept { mi_free(p); };
|
||||||
|
void operator delete[](void* p) noexcept { mi_free(p); };
|
||||||
|
|
||||||
|
void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
||||||
|
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
||||||
|
|
||||||
|
mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
|
||||||
|
mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }
|
||||||
|
|
||||||
|
mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
||||||
|
mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
||||||
|
|
||||||
|
// Not from mimalloc-new-delete.h, but necessary for EASTL
|
||||||
|
void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { return mi_new(size); }
|
||||||
|
|
||||||
|
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
|
||||||
|
void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); };
|
||||||
|
void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__cplusplus > 201402L || defined(__cpp_aligned_new))
|
||||||
|
void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
|
||||||
|
void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
|
||||||
|
void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
|
||||||
|
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
|
||||||
|
void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
|
||||||
|
void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
|
||||||
|
|
||||||
|
void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
|
||||||
|
void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
|
||||||
|
void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
|
||||||
|
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
|
||||||
|
|
||||||
|
// Not from mimalloc-new-delete.h, but necessary for EASTL
|
||||||
|
void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { return mi_new_aligned(size, alignment); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#if defined BIN2CPP_WINDOWS
|
||||||
|
#pragma warning(default: 4100 4559)
|
||||||
|
#elif defined BIN2CPP_LINUX
|
||||||
|
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#else
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPPLib)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPPLib)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPPExe)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP)
|
||||||
@@ -2,52 +2,64 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|||||||
project(${PackageName}Tests)
|
project(${PackageName}Tests)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME})
|
add_executable(${PROJECT_NAME})
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include)
|
file(GLOB_RECURSE BIN2CPPLIBTESTS_SOURCES
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE TEST_SOURCES
|
file(GLOB_RECURSE BIN2CPPLIBTESTS_HEADERS
|
||||||
CONFIGURE_DEPENDS
|
CONFIGURE_DEPENDS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
target_sources(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${TEST_SOURCES}
|
${BIN2CPPLIBTESTS_SOURCES}
|
||||||
|
PRIVATE
|
||||||
|
FILE_SET HEADERS
|
||||||
|
BASE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||||
|
FILES
|
||||||
|
${BIN2CPPLIBTESTS_HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE gtest::gtest Bin2CPPLib)
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Bin2CPPCompileAndLinkFlags
|
||||||
|
Bin2CPPLib
|
||||||
|
gtest::gtest)
|
||||||
|
|
||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
gtest_discover_tests(${PROJECT_NAME} XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}/TestResults/)
|
gtest_discover_tests(${PROJECT_NAME} XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}/TestResults/)
|
||||||
|
|
||||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${TEST_SOURCES})
|
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${BIN2CPPLIBTESTS_SOURCES} ${BIN2CPPLIBTESTS_HEADERS})
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Tests/Bin2CPP/${ParentFolder})
|
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Tests/Bin2CPP/${ParentFolder})
|
||||||
|
|
||||||
|
##################ASAN SETUP###################
|
||||||
|
|
||||||
|
if(${ASAN})
|
||||||
|
if (MSVC)
|
||||||
|
get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
||||||
|
set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll")
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Copying ASan DLL: ${ASAN_DLL} to $<TARGET_FILE_DIR:${PROJECT_NAME}>"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
##################COPY FIXTURE FOLDER###################
|
##################COPY FIXTURE FOLDER###################
|
||||||
|
|
||||||
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
|
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
|
||||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Track all fixture files
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
file(GLOB_RECURSE FIXTURE_FILES
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
|
||||||
CONFIGURE_DEPENDS
|
COMMENT "Copying Fixture folder ${CMAKE_CURRENT_SOURCE_DIR}/Fixture to $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture"
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Fixture/*
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(${PROJECT_NAME}Fixture
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
|
|
||||||
DEPENDS ${FIXTURE_FILES}
|
|
||||||
COMMENT "Copying Fixture folder for ${PROJECT_NAME}"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Fixture)
|
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME}Fixture PROPERTIES FOLDER UtilityTargets/Tests/Bin2CPP/${ParentFolder})
|
|
||||||
|
|
||||||
bin2cpp_setup_dependencies("Tests/Bin2CPP")
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Hello World
|
||||||
139
Bin2CPP/Tests/Bin2CPPLib/Generator.cpp
Normal file
139
Bin2CPP/Tests/Bin2CPPLib/Generator.cpp
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Generator.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Generator.hpp>
|
||||||
|
|
||||||
|
#include <Log.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
class GeneratorFixture: public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Singleton<Log>::Lifetime m_lifetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(GeneratorFixture, GenerateDefault)
|
||||||
|
{
|
||||||
|
Generator generator("Fixture/toto.txt");
|
||||||
|
EXPECT_TRUE(generator.Generate());
|
||||||
|
|
||||||
|
constexpr std::string_view expectedResult = R"(/**
|
||||||
|
* Auto-generated header from: toto.txt
|
||||||
|
* Generated by Bin2CPP
|
||||||
|
*
|
||||||
|
* DO NOT TOUCH
|
||||||
|
*/
|
||||||
|
#ifndef TOTO_TXT_HPP
|
||||||
|
#define TOTO_TXT_HPP
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline constexpr std::array<std::byte, 11> g_toto_txt = {
|
||||||
|
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||||
|
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||||
|
std::byte{0x64}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // TOTO_TXT_HPP
|
||||||
|
)";
|
||||||
|
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(GeneratorFixture, GenerateNamespace)
|
||||||
|
{
|
||||||
|
Generator generator("Fixture/toto.txt");
|
||||||
|
generator.SetMapping(MappingKey::NAMESPACE, "Test");
|
||||||
|
EXPECT_TRUE(generator.Generate());
|
||||||
|
|
||||||
|
constexpr std::string_view expectedResult = R"(/**
|
||||||
|
* Auto-generated header from: toto.txt
|
||||||
|
* Generated by Bin2CPP
|
||||||
|
*
|
||||||
|
* DO NOT TOUCH
|
||||||
|
*/
|
||||||
|
#ifndef TOTO_TXT_HPP
|
||||||
|
#define TOTO_TXT_HPP
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
inline constexpr std::array<std::byte, 11> g_toto_txt = {
|
||||||
|
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||||
|
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||||
|
std::byte{0x64}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Test
|
||||||
|
|
||||||
|
#endif // TOTO_TXT_HPP
|
||||||
|
)";
|
||||||
|
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(GeneratorFixture, GenerateCustomArray)
|
||||||
|
{
|
||||||
|
Generator generator("Fixture/toto.txt");
|
||||||
|
generator.SetMapping(MappingKey::ARRAY_TYPE, "eastl::array");
|
||||||
|
generator.SetMapping(MappingKey::ARRAY_TYPE_INCLUDE, "<EASTL/array.h>");
|
||||||
|
generator.SetMapping(MappingKey::ARRAY_NAME, "g_myArray");
|
||||||
|
EXPECT_TRUE(generator.Generate());
|
||||||
|
|
||||||
|
constexpr std::string_view expectedResult = R"(/**
|
||||||
|
* Auto-generated header from: toto.txt
|
||||||
|
* Generated by Bin2CPP
|
||||||
|
*
|
||||||
|
* DO NOT TOUCH
|
||||||
|
*/
|
||||||
|
#ifndef TOTO_TXT_HPP
|
||||||
|
#define TOTO_TXT_HPP
|
||||||
|
#include <EASTL/array.h>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline constexpr eastl::array<std::byte, 11> g_myArray = {
|
||||||
|
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||||
|
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||||
|
std::byte{0x64}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // TOTO_TXT_HPP
|
||||||
|
)";
|
||||||
|
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(GeneratorFixture, NonExistentFile)
|
||||||
|
{
|
||||||
|
Generator generator("Fixture/tata.txt");
|
||||||
|
EXPECT_FALSE(generator.Generate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(GeneratorFixture, Directory)
|
||||||
|
{
|
||||||
|
Generator generator("Fixture/");
|
||||||
|
EXPECT_FALSE(generator.Generate());
|
||||||
|
}
|
||||||
|
} // namespace Bin2CPP
|
||||||
76
Bin2CPP/Tests/Bin2CPPLib/Log.cpp
Normal file
76
Bin2CPP/Tests/Bin2CPPLib/Log.cpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Log.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Log.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <Assert.hpp>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
class LogFixture: public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Log m_log;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, GetLogger_ShouldReturnTheLogger)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(m_log.GetLogger());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogDebug)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
BIN2CPP_LOG_DEBUG("Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogTrace)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
|
||||||
|
BIN2CPP_LOG_TRACE("Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogInfo)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
BIN2CPP_LOG_INFO("Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogWarn)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
BIN2CPP_LOG_WARN("Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogError)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
BIN2CPP_LOG_ERROR("Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(LogFixture, LogFatal)
|
||||||
|
{
|
||||||
|
Singleton<Log>::Lifetime singletonLifetime;
|
||||||
|
BIN2CPP_LOG_FATAL("Hello");
|
||||||
|
}
|
||||||
|
} // namespace Bin2CPP
|
||||||
39
Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp
Normal file
39
Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file Singleton.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date February 2026
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Singleton.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace Bin2CPP
|
||||||
|
{
|
||||||
|
class SingletonFixture: public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Singleton<std::uint8_t>::Lifetime m_lifetime {8};
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(SingletonFixture, HasInstance_ShouldReturnTrueIfSingletonIsInitialized)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(Singleton<std::uint8_t>::HasInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(SingletonFixture, HasInstance_ShouldReturnFaleIfSingletonIsNotInitialized)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(Singleton<std::uint32_t>::HasInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(SingletonFixture, Instance_ShouldReturnTheInstance)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(Singleton<std::uint8_t>::Instance(), 8);
|
||||||
|
}
|
||||||
|
} // namespace Bin2CPP
|
||||||
23
CMake/Bin2CPPTargets.cmake
Normal file
23
CMake/Bin2CPPTargets.cmake
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
if(NOT TARGET Bin2CPP)
|
||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
find_program(BIN2CPP_EXECUTABLE
|
||||||
|
NAMES Bin2CPP
|
||||||
|
PATHS ENV PATH
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
find_program(BIN2CPP_EXECUTABLE
|
||||||
|
NAMES Bin2CPP
|
||||||
|
PATHS "${CMAKE_CURRENT_LIST_DIR}"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BIN2CPP_EXECUTABLE)
|
||||||
|
get_filename_component(BIN2CPP_EXECUTABLE "${BIN2CPP_EXECUTABLE}" ABSOLUTE)
|
||||||
|
add_executable(Bin2CPP IMPORTED)
|
||||||
|
set_property(TARGET Bin2CPP PROPERTY IMPORTED_LOCATION ${BIN2CPP_EXECUTABLE})
|
||||||
|
else()
|
||||||
|
message(WARNING "Bin2CPP executable not found in ${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
32
CMake/CustomTargets.cmake
Normal file
32
CMake/CustomTargets.cmake
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
foreach(CONFIG DEBUG RELWITHDEBINFO)
|
||||||
|
if("${CMAKE_EXE_LINKER_FLAGS_${CONFIG}}" MATCHES "/INCREMENTAL:NO")
|
||||||
|
string(REGEX REPLACE "/INCREMENTAL([^:]|$)" ""
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_${CONFIG}
|
||||||
|
"${CMAKE_EXE_LINKER_FLAGS_${CONFIG}}")
|
||||||
|
endif()
|
||||||
|
if("${CMAKE_SHARED_LINKER_FLAGS_${CONFIG}}" MATCHES "/INCREMENTAL:NO")
|
||||||
|
string(REGEX REPLACE "/INCREMENTAL([^:]|$)" ""
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_${CONFIG}
|
||||||
|
"${CMAKE_SHARED_LINKER_FLAGS_${CONFIG}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_library(Bin2CPPCompileAndLinkFlags INTERFACE)
|
||||||
|
|
||||||
|
target_compile_options(Bin2CPPCompileAndLinkFlags INTERFACE
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
|
||||||
|
$<$<CXX_COMPILER_ID:Clang,GNU>:-Wall -Wextra -Wpedantic -Werror>
|
||||||
|
$<$<AND:$<BOOL:${COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fprofile-instr-generate -fcoverage-mapping>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_options(Bin2CPPCompileAndLinkFlags INTERFACE
|
||||||
|
$<$<AND:$<BOOL:${COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fprofile-instr-generate>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(Bin2CPPCompileAndLinkFlags INTERFACE
|
||||||
|
$<$<CONFIG:Release>:BIN2CPP_OPTIMIZED>
|
||||||
|
$<$<CONFIG:Debug,RelWithDebInfo>:BIN2CPP_NOT_OPTIMIZED>
|
||||||
|
$<$<PLATFORM_ID:Windows>:BIN2CPP_WINDOWS>
|
||||||
|
$<$<PLATFORM_ID:Linux>:BIN2CPP_LINUX>
|
||||||
|
$<$<PLATFORM_ID:Windows>:NOMINMAX>
|
||||||
|
$<$<PLATFORM_ID:Windows>:WIN32_LEAN_AND_MEAN>)
|
||||||
@@ -5,18 +5,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(EASTL REQUIRED)
|
find_package(magic_enum REQUIRED)
|
||||||
find_package(mimalloc REQUIRED)
|
|
||||||
find_package(CLI11 REQUIRED)
|
find_package(CLI11 REQUIRED)
|
||||||
find_package(rapidhash REQUIRED)
|
|
||||||
find_package(quill REQUIRED)
|
find_package(quill REQUIRED)
|
||||||
|
|
||||||
if(${IS_MULTI_CONFIG})
|
if(${ASAN})
|
||||||
find_package(cpptrace REQUIRED)
|
find_package(mimalloc-asan REQUIRED)
|
||||||
elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
|
else()
|
||||||
find_package(cpptrace REQUIRED)
|
find_package(mimalloc REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(cpptrace REQUIRED)
|
||||||
|
|
||||||
if(BUILD_TESTS)
|
if(BUILD_TESTS)
|
||||||
find_package(GTest REQUIRED)
|
find_package(GTest REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
function(bin2cpp_setup_dependencies ParentFolder)
|
|
||||||
set(CONAN_DEPLOYER_DIR "${CMAKE_SOURCE_DIR}/build/full_deploy/host")
|
|
||||||
|
|
||||||
if(EXISTS ${CONAN_DEPLOYER_DIR})
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
||||||
file(GLOB_RECURSE SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.dll)
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
file(GLOB_RECURSE SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.so*)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(${IS_MULTI_CONFIG})
|
|
||||||
foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES})
|
|
||||||
foreach(file ${SHARED_BINARIES})
|
|
||||||
if(file MATCHES "/${CONFIG}/")
|
|
||||||
list(APPEND SHARED_BINARIES_${CONFIG} ${file})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_custom_target(${PROJECT_NAME}CopySharedBinaries
|
|
||||||
ALL DEPENDS SHARED_BINARIES
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_if_different,true> ${SHARED_BINARIES_Debug} $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Release>,copy_if_different,true> ${SHARED_BINARIES_Release} $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:RelWithDebInfo>,copy_if_different,true> ${SHARED_BINARIES_RelWithDebInfo} $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMENT "Copy shared binaries for ${PROJECT_NAME}"
|
|
||||||
)
|
|
||||||
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries)
|
|
||||||
set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder})
|
|
||||||
|
|
||||||
else()
|
|
||||||
foreach(file ${SHARED_BINARIES})
|
|
||||||
if(file MATCHES "/${CMAKE_BUILD_TYPE}/")
|
|
||||||
list(APPEND SHARED_BINARIES_${CMAKE_BUILD_TYPE} ${file})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_custom_target(${PROJECT_NAME}CopySharedBinaries ALL
|
|
||||||
DEPENDS ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}} $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
|
||||||
COMMENT "Copy shared binaries for ${PROJECT_NAME}"
|
|
||||||
)
|
|
||||||
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries)
|
|
||||||
set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
||||||
add_custom_target(${PROJECT_NAME}PatchMinject ALL
|
|
||||||
COMMAND ${MINJECT_EXECUTABLE} -i -f $<TARGET_FILE:${PROJECT_NAME}>
|
|
||||||
COMMENT "Patching ${PROJECT_NAME} to ensure mimalloc dynamic override"
|
|
||||||
)
|
|
||||||
add_dependencies(${PROJECT_NAME}PatchMinject ${PROJECT_NAME})
|
|
||||||
set_target_properties(${PROJECT_NAME}PatchMinject PROPERTIES FOLDER "UtilityTargets/${ParentFolder}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endfunction()
|
|
||||||
@@ -1,31 +1,25 @@
|
|||||||
cmake_minimum_required(VERSION 3.24)
|
cmake_minimum_required(VERSION 3.26)
|
||||||
|
|
||||||
project(Bin2CPP VERSION 0.1.0
|
project(Bin2CPP VERSION 0.1.0
|
||||||
DESCRIPTION "Bin2CPP"
|
DESCRIPTION "Bin2CPP"
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
||||||
|
|
||||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||||
|
|
||||||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
|
||||||
|
include(${CMAKE_SOURCE_DIR}/CMake/CustomTargets.cmake)
|
||||||
|
include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake)
|
||||||
|
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "" FORCE)
|
set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "" FORCE)
|
||||||
|
|
||||||
option(BUILD_TESTS OFF)
|
option(BUILD_TESTS OFF)
|
||||||
|
option(ASAN OFF)
|
||||||
include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake)
|
option(COVERAGE OFF)
|
||||||
include(${CMAKE_SOURCE_DIR}/CMake/Utils.cmake)
|
|
||||||
|
|
||||||
find_program(MINJECT_EXECUTABLE NAMES minject)
|
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
set(CMAKE_OPTIMIZE_DEPENDENCIES 1)
|
set(CMAKE_OPTIMIZE_DEPENDENCIES 1)
|
||||||
|
|
||||||
add_compile_definitions(
|
|
||||||
$<$<PLATFORM_ID:Windows>:NOMINMAX>
|
|
||||||
$<$<PLATFORM_ID:Windows>:WIN32_LEAN_AND_MEAN>)
|
|
||||||
|
|
||||||
if(BUILD_TESTS)
|
if(BUILD_TESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
endif()
|
endif()
|
||||||
@@ -40,6 +34,3 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP/Sources)
|
|||||||
if(${BUILD_TESTS})
|
if(${BUILD_TESTS})
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP/Tests)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP/Tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_target(NatVis SOURCES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/EASTL/EASTL.natvis)
|
|
||||||
32
ConanProfiles/clang
Normal file
32
ConanProfiles/clang
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[settings]
|
||||||
|
os=Linux
|
||||||
|
arch=x86_64
|
||||||
|
compiler=clang
|
||||||
|
compiler.version=20
|
||||||
|
compiler.libcxx=libstdc++11
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Release
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'}
|
||||||
|
|
||||||
|
tools.system.package_manager:mode=install
|
||||||
|
tools.system.package_manager:sudo=True
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["-fuse-ld=mold", "-flto"]
|
||||||
|
tools.build:sharedlinkflags=["-fuse-ld=mold", "-flto"]
|
||||||
|
|
||||||
|
tools.build:cflags=["-flto"]
|
||||||
|
tools.build:cxxflags=["-flto"]
|
||||||
|
|
||||||
|
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
|
||||||
|
|
||||||
|
tools.cmake.cmaketoolchain:generator=Ninja
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
30
ConanProfiles/clang_coverage
Normal file
30
ConanProfiles/clang_coverage
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[settings]
|
||||||
|
os=Linux
|
||||||
|
arch=x86_64
|
||||||
|
compiler=clang
|
||||||
|
compiler.version=20
|
||||||
|
compiler.libcxx=libstdc++11
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Debug
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'}
|
||||||
|
|
||||||
|
tools.system.package_manager:mode=install
|
||||||
|
tools.system.package_manager:sudo=True
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["-fuse-ld=mold"]
|
||||||
|
tools.build:sharedlinkflags=["-fuse-ld=mold"]
|
||||||
|
|
||||||
|
tools.cmake.cmaketoolchain:generator=Ninja
|
||||||
|
|
||||||
|
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
|
Bin2CPP/*:coverage=True
|
||||||
29
ConanProfiles/clangd
Normal file
29
ConanProfiles/clangd
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[settings]
|
||||||
|
os=Linux
|
||||||
|
arch=x86_64
|
||||||
|
compiler=clang
|
||||||
|
compiler.version=20
|
||||||
|
compiler.libcxx=libstdc++11
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Debug
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'}
|
||||||
|
|
||||||
|
tools.system.package_manager:mode=install
|
||||||
|
tools.system.package_manager:sudo=True
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["-fuse-ld=mold"]
|
||||||
|
tools.build:sharedlinkflags=["-fuse-ld=mold"]
|
||||||
|
|
||||||
|
tools.cmake.cmaketoolchain:generator=Ninja
|
||||||
|
|
||||||
|
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
33
ConanProfiles/clangd_asan
Normal file
33
ConanProfiles/clangd_asan
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[settings]
|
||||||
|
os=Linux
|
||||||
|
arch=x86_64
|
||||||
|
compiler=clang
|
||||||
|
compiler.version=20
|
||||||
|
compiler.libcxx=libstdc++11
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Debug
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'}
|
||||||
|
|
||||||
|
tools.system.package_manager:mode=install
|
||||||
|
tools.system.package_manager:sudo=True
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["-fuse-ld=mold", "-fsanitize=address,undefined,leak"]
|
||||||
|
tools.build:sharedlinkflags=["-fuse-ld=mold", "-fsanitize=address,undefined,leak"]
|
||||||
|
|
||||||
|
tools.build:cflags=["-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"]
|
||||||
|
tools.build:cxxflags=["-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"]
|
||||||
|
|
||||||
|
tools.cmake.cmaketoolchain:generator=Ninja
|
||||||
|
|
||||||
|
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:asan=True
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
24
ConanProfiles/msvc
Normal file
24
ConanProfiles/msvc
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[settings]
|
||||||
|
os=Windows
|
||||||
|
arch=x86_64
|
||||||
|
compiler=msvc
|
||||||
|
compiler.version=195
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Release
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["/LTCG", "/INCREMENTAL:NO"]
|
||||||
|
tools.build:sharedlinkflags=["/LTCG", "/INCREMENTAL:NO"]
|
||||||
|
|
||||||
|
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1", "/GL"]
|
||||||
|
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
19
ConanProfiles/msvc_ccache.cmake
Normal file
19
ConanProfiles/msvc_ccache.cmake
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake
|
||||||
|
|
||||||
|
find_program(ccache_exe ccache)
|
||||||
|
if(ccache_exe)
|
||||||
|
file(COPY_FILE
|
||||||
|
${ccache_exe} ${CMAKE_BINARY_DIR}/cl.exe
|
||||||
|
ONLY_IF_DIFFERENT)
|
||||||
|
|
||||||
|
# By default Visual Studio generators will use /Zi which is not compatible
|
||||||
|
# with ccache, so tell Visual Studio to use /Z7 instead.
|
||||||
|
message(STATUS "Setting MSVC debug information format to 'Embedded'")
|
||||||
|
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
|
||||||
|
|
||||||
|
set(CMAKE_VS_GLOBALS
|
||||||
|
"CLToolExe=cl.exe"
|
||||||
|
"CLToolPath=${CMAKE_BINARY_DIR}"
|
||||||
|
"UseMultiToolTask=true"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
20
ConanProfiles/msvcd
Normal file
20
ConanProfiles/msvcd
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[settings]
|
||||||
|
os=Windows
|
||||||
|
arch=x86_64
|
||||||
|
compiler=msvc
|
||||||
|
compiler.version=195
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Debug
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake
|
||||||
|
|
||||||
|
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
|
||||||
|
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
25
ConanProfiles/msvcd_asan
Normal file
25
ConanProfiles/msvcd_asan
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[settings]
|
||||||
|
os=Windows
|
||||||
|
arch=x86_64
|
||||||
|
compiler=msvc
|
||||||
|
compiler.version=195
|
||||||
|
compiler.cppstd=20
|
||||||
|
compiler.cstd=17
|
||||||
|
compiler.runtime=static
|
||||||
|
build_type=Debug
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake
|
||||||
|
|
||||||
|
tools.build:exelinkflags=["/INCREMENTAL:NO"]
|
||||||
|
tools.build:sharedlinkflags=["/INCREMENTAL:NO"]
|
||||||
|
|
||||||
|
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
|
||||||
|
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||||
|
|
||||||
|
[tool_requires]
|
||||||
|
!cmake/*: cmake/[>=4.2]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
Bin2CPP/*:asan=True
|
||||||
|
Bin2CPP/*:build_tests=True
|
||||||
761
Vendor/NatVis/EASTL/EASTL.natvis
vendored
761
Vendor/NatVis/EASTL/EASTL.natvis
vendored
@@ -1,761 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This is a Microsoft natvis file, which allows visualization of complex variables in the
|
|
||||||
Microsoft debugger starting with VS2012. It's a successor to the AutoExp.dat file format.
|
|
||||||
|
|
||||||
This file needs to go into your C:\Users\<user>\Documents\Visual Studio 2011\Visualizers\
|
|
||||||
folder. Microsoft documentation states that it should go into a 2012 folder, but testing
|
|
||||||
in June of 2013 suggests that it still needs to be the 2011 folder.
|
|
||||||
|
|
||||||
You don't need to restart Visual Studio to use it, you just need to restart the debug
|
|
||||||
session. You can have multiple .natvis files and they will all be used.
|
|
||||||
|
|
||||||
VS2017 natvis documentation:
|
|
||||||
https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects
|
|
||||||
-->
|
|
||||||
|
|
||||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
|
||||||
|
|
||||||
<Type Name="eastl::unique_ptr<*>">
|
|
||||||
<DisplayString Condition="mPair.mFirst != nullptr">({(void*)mPair.mFirst} = {*mPair.mFirst})</DisplayString>
|
|
||||||
<DisplayString Condition="mPair.mFirst == nullptr">({nullptr})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[pointer]">(void*)mPair.mFirst</Item>
|
|
||||||
<Item Name="[value]">*mPair.mFirst</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::shared_ptr<*>">
|
|
||||||
<DisplayString Condition="mpValue != nullptr">({(void*)mpValue} = {*mpValue})</DisplayString>
|
|
||||||
<DisplayString Condition="mpValue == nullptr">({nullptr})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[pointer]">(void*)mpValue</Item>
|
|
||||||
<Item Name="[value]">*mpValue</Item>
|
|
||||||
<Item Name="[reference count]">mpRefCount->mRefCount</Item>
|
|
||||||
<Item Name="[weak reference count]">mpRefCount->mWeakRefCount</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::weak_ptr<*>">
|
|
||||||
<DisplayString>{((mpRefCount && mpRefCount->mRefCount) ? mpValue : nullptr)}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>mpRefCount && mpRefCount->mRefCount ? mpValue : nullptr</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::array<*,*>">
|
|
||||||
<DisplayString Condition="$T2 == 0">[{$T2}] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 1">[{$T2}] {{ {*mValue} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 2">[{$T2}] {{ {*mValue}, {*(mValue+1)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 3">[{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 4">[{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 5">[{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 == 6">[{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="$T2 > 6">[{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)}, ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">$T2</Item>
|
|
||||||
<ArrayItems>
|
|
||||||
<Size>$T2</Size>
|
|
||||||
<ValuePointer>mValue</ValuePointer>
|
|
||||||
</ArrayItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::basic_string<*>">
|
|
||||||
<DisplayString Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">"{mPair.mFirst.heap.mpBegin,sb}"</DisplayString>
|
|
||||||
<DisplayString Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">"{mPair.mFirst.sso.mData,sb}"</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[length]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.heap.mnSize</Item>
|
|
||||||
<Item Name="[capacity]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">(mPair.mFirst.heap.mnCapacity & ~kHeapMask)</Item>
|
|
||||||
<Item Name="[value]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.heap.mpBegin,sb</Item>
|
|
||||||
|
|
||||||
<Item Name="[length]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">(SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize)</Item>
|
|
||||||
<Item Name="[capacity]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">SSOLayout::SSO_CAPACITY</Item>
|
|
||||||
<Item Name="[value]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.sso.mData,sb</Item>
|
|
||||||
|
|
||||||
<Item Name="[uses heap]">!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::basic_string<wchar_t,*>">
|
|
||||||
<DisplayString Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">{mPair.mFirst.heap.mpBegin,su}</DisplayString>
|
|
||||||
<DisplayString Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">{mPair.mFirst.sso.mData,su}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[length]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.heap.mnSize</Item>
|
|
||||||
<Item Name="[capacity]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">(mPair.mFirst.heap.mnCapacity & ~kHeapMask)</Item>
|
|
||||||
<Item Name="[value]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.heap.mpBegin,su</Item>
|
|
||||||
|
|
||||||
<Item Name="[length]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">(SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize)</Item>
|
|
||||||
<Item Name="[capacity]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">SSOLayout::SSO_CAPACITY</Item>
|
|
||||||
<Item Name="[value]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)">mPair.mFirst.sso.mData,su</Item>
|
|
||||||
|
|
||||||
<Item Name="[uses heap]">!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask)</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::pair<*>">
|
|
||||||
<DisplayString>({first}, {second})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="first">first</Item>
|
|
||||||
<Item Name="second">second</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::span<*>">
|
|
||||||
<DisplayString Condition="mnSize == 0">[{mnSize}] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 1">[{mnSize}] {{ {*mpData} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 2">[{mnSize}] {{ {*mpData}, {*(mpData+1)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 3">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 4">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 5">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 6">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize > 6">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)}, ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">mnSize</Item>
|
|
||||||
<ArrayItems>
|
|
||||||
<Size>mnSize</Size>
|
|
||||||
<ValuePointer>mpData</ValuePointer>
|
|
||||||
</ArrayItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::VectorBase<*>">
|
|
||||||
<DisplayString Condition="mpEnd == mpBegin">[{mpEnd - mpBegin}] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 1">[{mpEnd - mpBegin}] {{ {*mpBegin} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 2">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 3">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 4">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 5">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin == 6">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mpEnd - mpBegin > 6">[{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)}, ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">mpEnd - mpBegin</Item>
|
|
||||||
<Item Name="[capacity]">mCapacityAllocator.mFirst - mpBegin</Item>
|
|
||||||
<ArrayItems>
|
|
||||||
<Size>mpEnd - mpBegin</Size>
|
|
||||||
<ValuePointer>mpBegin</ValuePointer>
|
|
||||||
</ArrayItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::DequeBase<*,*,*>">
|
|
||||||
<DisplayString Condition="mItBegin.mpCurrent == mItEnd.mpCurrent">
|
|
||||||
[0] {{}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) == 1">
|
|
||||||
[1] {{ {*mItBegin.mpCurrent} }}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) != 0">
|
|
||||||
[{(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin)}]
|
|
||||||
{{
|
|
||||||
{*mItBegin.mpCurrent},
|
|
||||||
...
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin)</Item>
|
|
||||||
<IndexListItems>
|
|
||||||
<Size>(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin)</Size>
|
|
||||||
<ValueNode>mItBegin.mpCurrentArrayPtr[(mItBegin.mpCurrent-mItBegin.mpBegin + $i) / $T3][(mItBegin.mpCurrent-mItBegin.mpBegin + $i) % $T3]</ValueNode>
|
|
||||||
</IndexListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::DequeIterator<*>">
|
|
||||||
<DisplayString>{*mpCurrent}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="Value">*mpCurrent</Item>
|
|
||||||
<Item Name="Previous" Condition="mpCurrent == mpBegin">*(*(mpCurrentArrayPtr-1) + (mpEnd-mpBegin) - 1)</Item>
|
|
||||||
<Item Name="Previous" Condition="mpCurrent != mpBegin">*(mpCurrent-1)</Item>
|
|
||||||
<Item Name="Next" Condition="mpCurrent+1 == mpEnd">**(mpCurrentArrayPtr+1)</Item>
|
|
||||||
<Item Name="Next" Condition="mpCurrent+1 != mpEnd">*(mpCurrent+1)</Item>
|
|
||||||
<Item Name="Begin">mpCurrent == mpBegin</Item>
|
|
||||||
<Item Name="End">mpCurrent+1 == mpEnd</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::queue<*>">
|
|
||||||
<AlternativeType Name="eastl::priority_queue<*>" />
|
|
||||||
<AlternativeType Name="eastl::stack<*>" />
|
|
||||||
<DisplayString>{c}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>c</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::ListBase<*>">
|
|
||||||
<DisplayString Condition="mNodeAllocator.mFirst.mpNext == &mNodeAllocator.mFirst">
|
|
||||||
[0] {{}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNodeAllocator.mFirst.mpNext != &mNodeAllocator.mFirst && mNodeAllocator.mFirst.mpNext->mpNext == &mNodeAllocator.mFirst">
|
|
||||||
[1] {{ {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue} }}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNodeAllocator.mFirst.mpNext != &mNodeAllocator.mFirst && mNodeAllocator.mFirst.mpNext->mpNext != &mNodeAllocator.mFirst && mNodeAllocator.mFirst.mpNext->mpNext->mpNext == &mNodeAllocator.mFirst">
|
|
||||||
[2]
|
|
||||||
{{
|
|
||||||
{((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue},
|
|
||||||
{((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue}
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNodeAllocator.mFirst.mpNext != &mNodeAllocator.mFirst && mNodeAllocator.mFirst.mpNext->mpNext != &mNodeAllocator.mFirst && mNodeAllocator.mFirst.mpNext->mpNext->mpNext != &mNodeAllocator.mFirst">
|
|
||||||
[?]
|
|
||||||
{{
|
|
||||||
{((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue},
|
|
||||||
{((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue},
|
|
||||||
...
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Synthetic Name="NOTE!">
|
|
||||||
<DisplayString>Content of lists will repeat indefinitely. Keep that in mind!</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>mNodeAllocator.mFirst.mpNext</HeadPointer>
|
|
||||||
<NextPointer>mpNext</NextPointer>
|
|
||||||
<ValueNode>((eastl::ListNode<$T1>*)this)->mValue</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::ListNode<*>">
|
|
||||||
<DisplayString>{mValue}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="Value">mValue</Item>
|
|
||||||
<Item Name="Next">*(eastl::ListNode<$T1>*)mpNext</Item>
|
|
||||||
<Item Name="Previous">*(eastl::ListNode<$T1>*)mpPrev</Item>
|
|
||||||
<Synthetic Name="NOTE!">
|
|
||||||
<DisplayString>Content of lists will repeat indefinitely. Keep that in mind!</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<Synthetic Name="List">
|
|
||||||
<DisplayString>The rest of the list follows:</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>(eastl::ListNode<$T1>*)mpNext->mpNext</HeadPointer>
|
|
||||||
<NextPointer>(eastl::ListNode<$T1>*)mpNext</NextPointer>
|
|
||||||
<ValueNode>mValue</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::ListIterator<*>">
|
|
||||||
<DisplayString>{*mpNode}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>*(eastl::ListNode<$T1>*)mpNode</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::SListBase<*>">
|
|
||||||
<DisplayString Condition="mNode.mpNext == 0">
|
|
||||||
[0] {{}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNode.mpNext != 0 && mNode.mpNext->mpNext == 0">
|
|
||||||
[1]
|
|
||||||
{{
|
|
||||||
{((eastl::SListNode<$T1>*)mNode.mpNext)->mValue}
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNode.mpNext != 0 && mNode.mpNext->mpNext != 0 && mNode.mpNext->mpNext->mpNext == 0">
|
|
||||||
[2]
|
|
||||||
{{
|
|
||||||
{((eastl::SListNode<$T1>*)mNode.mpNext)->mValue},
|
|
||||||
{((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue}
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mNode.mpNext != 0 && mNode.mpNext->mpNext != 0 && mNode.mpNext->mpNext->mpNext != 0">
|
|
||||||
[?]
|
|
||||||
{{
|
|
||||||
{((eastl::SListNode<$T1>*)mNode.mpNext)->mValue},
|
|
||||||
{((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue},
|
|
||||||
...
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>mNode.mpNext</HeadPointer>
|
|
||||||
<NextPointer>mpNext</NextPointer>
|
|
||||||
<ValueNode>((eastl::SListNode<$T1>*)this)->mValue</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::SListNode<*>">
|
|
||||||
<DisplayString>{mValue}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="Value">mValue</Item>
|
|
||||||
<Item Name="Next">*(eastl::SListNode<$T1>*)mpNext</Item>
|
|
||||||
<Synthetic Name="List">
|
|
||||||
<DisplayString>The rest of the list follows:</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>mpNext == nullptr ? nullptr : (eastl::SListNode<$T1>*)mpNext->mpNext</HeadPointer>
|
|
||||||
<NextPointer>(eastl::SListNode<$T1>*)mpNext</NextPointer>
|
|
||||||
<ValueNode>mValue</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::SListIterator<*>">
|
|
||||||
<DisplayString>{*mpNode}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>*(eastl::SListNode<$T1>*)mpNode</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::intrusive_list_base">
|
|
||||||
<DisplayString Condition="mAnchor.mpNext == &mAnchor">[0] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="mAnchor.mpNext != &mAnchor && mAnchor.mpNext->mpNext == &mAnchor">[1] {{ {mAnchor.mpNext} }}</DisplayString>
|
|
||||||
<DisplayString Condition="mAnchor.mpNext != &mAnchor && mAnchor.mpNext->mpNext != &mAnchor">[?] {{ {mAnchor.mpNext}, ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Synthetic Name="NOTE!">
|
|
||||||
<DisplayString>Content of intrusive lists will repeat indefinitely. Keep that in mind!</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>mAnchor.mpNext</HeadPointer>
|
|
||||||
<NextPointer>mpNext</NextPointer>
|
|
||||||
<ValueNode>*this</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::intrusive_list_iterator<*>">
|
|
||||||
<DisplayString>{*($T1*)mpNode}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>*($T1*)mpNode</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::set<*>">
|
|
||||||
<AlternativeType Name="eastl::multiset<*>" />
|
|
||||||
<DisplayString Condition="mnSize == 0">
|
|
||||||
[0] {{}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 1">
|
|
||||||
[1]
|
|
||||||
{{
|
|
||||||
{((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue}
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize > 1">
|
|
||||||
[{mnSize}]
|
|
||||||
{{
|
|
||||||
{((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue},
|
|
||||||
...
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">mnSize</Item>
|
|
||||||
<TreeItems>
|
|
||||||
<Size>mnSize</Size>
|
|
||||||
<HeadPointer>mAnchor.mpNodeParent</HeadPointer>
|
|
||||||
<LeftPointer>mpNodeLeft</LeftPointer>
|
|
||||||
<RightPointer>mpNodeRight</RightPointer>
|
|
||||||
<ValueNode>((eastl::rbtree_node<$T1>*)this)->mValue</ValueNode>
|
|
||||||
</TreeItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::rbtree<*,*>">
|
|
||||||
<DisplayString Condition="mnSize == 0">
|
|
||||||
[0] {{}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize == 1">
|
|
||||||
[1]
|
|
||||||
{{
|
|
||||||
{((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue}
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<DisplayString Condition="mnSize > 1">
|
|
||||||
[{mnSize}]
|
|
||||||
{{
|
|
||||||
{((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue},
|
|
||||||
...
|
|
||||||
}}
|
|
||||||
</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[size]">mnSize</Item>
|
|
||||||
<TreeItems>
|
|
||||||
<Size>mnSize</Size>
|
|
||||||
<HeadPointer>mAnchor.mpNodeParent</HeadPointer>
|
|
||||||
<LeftPointer>mpNodeLeft</LeftPointer>
|
|
||||||
<RightPointer>mpNodeRight</RightPointer>
|
|
||||||
<ValueNode>((eastl::rbtree_node<$T2>*)this)->mValue</ValueNode>
|
|
||||||
</TreeItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::rbtree_node<*>">
|
|
||||||
<DisplayString>{mValue}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="Value">mValue</Item>
|
|
||||||
<Synthetic Name="NOTE!">
|
|
||||||
<DisplayString>It is possible to expand parents that do not exist.</DisplayString>
|
|
||||||
</Synthetic>
|
|
||||||
<Item Name="Parent">*(eastl::rbtree_node<$T1>*)mpNodeParent</Item>
|
|
||||||
<Item Name="Left">*(eastl::rbtree_node<$T1>*)mpNodeLeft</Item>
|
|
||||||
<Item Name="Right">*(eastl::rbtree_node<$T1>*)mpNodeRight</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::rbtree_iterator<*>">
|
|
||||||
<DisplayString>{*(eastl::rbtree_node<$T1>*)mpNode}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="Node">*(eastl::rbtree_node<$T1>*)mpNode</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::hashtable<*>">
|
|
||||||
<DisplayString Condition="mnElementCount == 0">[{mnElementCount}] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="mnElementCount != 0">[{mnElementCount}] {{ ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ArrayItems IncludeView="detailed">
|
|
||||||
<Size>mnBucketCount</Size>
|
|
||||||
<ValuePointer>mpBucketArray</ValuePointer>
|
|
||||||
</ArrayItems>
|
|
||||||
<CustomListItems ExcludeView="detailed">
|
|
||||||
<Variable Name="bucketIndex" InitialValue="0"/>
|
|
||||||
<Variable Name="entry" InitialValue ="mpBucketArray[bucketIndex]"/>
|
|
||||||
<Loop>
|
|
||||||
<Item Condition="entry != nullptr">entry->mValue</Item>
|
|
||||||
<If Condition="entry != nullptr">
|
|
||||||
<Exec>entry = entry->mpNext</Exec>
|
|
||||||
</If>
|
|
||||||
<If Condition="entry == nullptr">
|
|
||||||
<Exec>bucketIndex++</Exec>
|
|
||||||
<Break Condition="bucketIndex == mnBucketCount"/>
|
|
||||||
<Exec>entry = mpBucketArray[bucketIndex]</Exec>
|
|
||||||
</If>
|
|
||||||
</Loop>
|
|
||||||
</CustomListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<!-- specifically for hash_map (instead of base implementation hashtable),
|
|
||||||
show the key as name, and value as value, instead of index -> pair<key, value> -->
|
|
||||||
<Type Name="eastl::hash_map<*>">
|
|
||||||
<DisplayString Condition="mnElementCount == 0">[{mnElementCount}] {{}}</DisplayString>
|
|
||||||
<DisplayString Condition="mnElementCount != 0">[{mnElementCount}] {{ ... }}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<CustomListItems ExcludeView="detailed">
|
|
||||||
<Variable Name="bucketIndex" InitialValue="0"/>
|
|
||||||
<Variable Name="entry" InitialValue ="mpBucketArray[bucketIndex]"/>
|
|
||||||
<Loop>
|
|
||||||
<Item Name="[{entry->mValue.first}]" Condition="entry != nullptr">entry->mValue.second</Item>
|
|
||||||
<If Condition="entry != nullptr">
|
|
||||||
<Exec>entry = entry->mpNext</Exec>
|
|
||||||
</If>
|
|
||||||
<If Condition="entry == nullptr">
|
|
||||||
<Exec>bucketIndex++</Exec>
|
|
||||||
<Break Condition="bucketIndex == mnBucketCount"/>
|
|
||||||
<Exec>entry = mpBucketArray[bucketIndex]</Exec>
|
|
||||||
</If>
|
|
||||||
</Loop>
|
|
||||||
</CustomListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::hash_node<*>">
|
|
||||||
<DisplayString Condition="this != 0 && mpNext != 0"> {mValue}, {*mpNext}</DisplayString>
|
|
||||||
<DisplayString Condition="this != 0 && mpNext == 0"> {mValue}</DisplayString>
|
|
||||||
<DisplayString Condition="this == 0"></DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<LinkedListItems>
|
|
||||||
<HeadPointer>this</HeadPointer>
|
|
||||||
<NextPointer>mpNext</NextPointer>
|
|
||||||
<ValueNode>mValue</ValueNode>
|
|
||||||
</LinkedListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::hashtable_iterator_base<*>">
|
|
||||||
<DisplayString>{mpNode->mValue}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>mpNode->mValue</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::reverse_iterator<*>">
|
|
||||||
<DisplayString>{*(mIterator-1)}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>mIterator-1</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::bitset<*>">
|
|
||||||
<DisplayString>{{count = {kSize}}}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[count]">kSize</Item>
|
|
||||||
<CustomListItems>
|
|
||||||
<Variable Name="iWord" InitialValue="0" />
|
|
||||||
<Variable Name="iBitInWord" InitialValue="0" />
|
|
||||||
<Variable Name="bBitValue" InitialValue="false" />
|
|
||||||
|
|
||||||
<Size>kSize</Size>
|
|
||||||
|
|
||||||
<Loop>
|
|
||||||
<Exec>bBitValue = ((mWord[iWord] >> iBitInWord) % 2) != 0 ? true : false</Exec>
|
|
||||||
<Item>bBitValue</Item>
|
|
||||||
<Exec>iBitInWord++</Exec>
|
|
||||||
<If Condition="iBitInWord == kBitsPerWord">
|
|
||||||
<Exec>iWord++</Exec>
|
|
||||||
<Exec>iBitInWord = 0</Exec>
|
|
||||||
</If>
|
|
||||||
</Loop>
|
|
||||||
</CustomListItems>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::ring_buffer<*,*,*>">
|
|
||||||
<DisplayString>{c}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>c</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::basic_string_view<*>">
|
|
||||||
<DisplayString>{mpBegin,[mnCount]}</DisplayString>
|
|
||||||
<StringView>mpBegin,[mnCount]</StringView>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::compressed_pair_imp<*>">
|
|
||||||
<DisplayString Condition="($T3) == 0" Optional="true">({mFirst}, {mSecond})</DisplayString>
|
|
||||||
<DisplayString Condition="($T3) == 1" Optional="true">({mSecond})</DisplayString>
|
|
||||||
<DisplayString Condition="($T3) == 2" Optional="true">({mFirst})</DisplayString>
|
|
||||||
<DisplayString Condition="($T3) == 3" Optional="true">(empty)</DisplayString>
|
|
||||||
<DisplayString Condition="($T3) == 4" Optional="true">(empty)</DisplayString>
|
|
||||||
<DisplayString Condition="($T3) == 5" Optional="true">({mFirst}, {mSecond})</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::optional<*>">
|
|
||||||
<Intrinsic Name="value" Expression="*($T1*)&val"/>
|
|
||||||
<DisplayString Condition="!engaged">nullopt</DisplayString>
|
|
||||||
<DisplayString Condition="engaged">{value()}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Condition="engaged" Name="value">value()</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::ratio<*>">
|
|
||||||
<DisplayString>{$T1} to {$T2}}</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<1,1000000000> >">
|
|
||||||
<DisplayString>{mRep} nanoseconds</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<1,1000000> >">
|
|
||||||
<DisplayString>{mRep} microseconds</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<1,1000> >">
|
|
||||||
<DisplayString>{mRep} milliseconds</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<1,1> >">
|
|
||||||
<DisplayString>{mRep} seconds</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<60,1> >">
|
|
||||||
<DisplayString>{mRep} minutes</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<3600,1> >">
|
|
||||||
<DisplayString>{mRep} hours</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::chrono::duration<*,eastl::ratio<*,*> >">
|
|
||||||
<DisplayString>{mRep} duration with ratio = [{$T2} : {$T3}] </DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::function<*>">
|
|
||||||
<DisplayString Condition="mInvokeFuncPtr == nullptr">empty</DisplayString>
|
|
||||||
<DisplayString>{mInvokeFuncPtr}</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::reference_wrapper<*>">
|
|
||||||
<DisplayString>{*val}</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This implementation isn't ideal because it can't switch between showing inline value vs values stored in a heap allocation.
|
|
||||||
We are hitting the limit of natvis scripting that we can't workaround unless we change the implementation of eastl::any.
|
|
||||||
-->
|
|
||||||
<Type Name="eastl::any">
|
|
||||||
<DisplayString Condition="m_handler == nullptr">empty</DisplayString>
|
|
||||||
<DisplayString Condition="m_handler != nullptr">{m_storage.external_storage}</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::atomic<*>">
|
|
||||||
<DisplayString>{mAtomic}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<ExpandedItem>mAtomic</ExpandedItem>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::atomic_flag">
|
|
||||||
<DisplayString>{mFlag.mAtomic}</DisplayString>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::variant<*>">
|
|
||||||
<Intrinsic Name="index" Expression="(int)mIndex"/>
|
|
||||||
<DisplayString Condition="index() == size_t(-1)">[valueless_by_exception]</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 0" Optional="true">{{ index=0, value={($T1*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 1" Optional="true">{{ index=1, value={($T2*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 2" Optional="true">{{ index=2, value={($T3*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 3" Optional="true">{{ index=3, value={($T4*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 4" Optional="true">{{ index=4, value={($T5*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 5" Optional="true">{{ index=5, value={($T6*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 6" Optional="true">{{ index=6, value={($T7*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 7" Optional="true">{{ index=7, value={($T8*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 8" Optional="true">{{ index=8, value={($T9*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 9" Optional="true">{{ index=9, value={($T10*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 10" Optional="true">{{ index=10, value={($T11*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 11" Optional="true">{{ index=11, value={($T12*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 12" Optional="true">{{ index=12, value={($T13*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 13" Optional="true">{{ index=13, value={($T14*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 14" Optional="true">{{ index=14, value={($T15*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 15" Optional="true">{{ index=15, value={($T16*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 16" Optional="true">{{ index=16, value={($T17*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 17" Optional="true">{{ index=17, value={($T18*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 18" Optional="true">{{ index=18, value={($T19*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 19" Optional="true">{{ index=19, value={($T20*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 20" Optional="true">{{ index=20, value={($T21*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 21" Optional="true">{{ index=21, value={($T22*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 22" Optional="true">{{ index=22, value={($T23*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 23" Optional="true">{{ index=23, value={($T24*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 24" Optional="true">{{ index=24, value={($T25*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 25" Optional="true">{{ index=25, value={($T26*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 26" Optional="true">{{ index=26, value={($T27*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 27" Optional="true">{{ index=27, value={($T28*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 28" Optional="true">{{ index=28, value={($T29*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 29" Optional="true">{{ index=29, value={($T30*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<DisplayString Condition="index() == 30" Optional="true">{{ index=30, value={($T31*)mStorage.mBuffer.mCharData}}</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="index">index()</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 0" Optional="true">($T1*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 1" Optional="true">($T2*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 2" Optional="true">($T3*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 3" Optional="true">($T4*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 4" Optional="true">($T5*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 5" Optional="true">($T6*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 6" Optional="true">($T7*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 7" Optional="true">($T8*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 8" Optional="true">($T9*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 9" Optional="true">($T10*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 10" Optional="true">($T11*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 11" Optional="true">($T12*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 12" Optional="true">($T13*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 13" Optional="true">($T14*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 14" Optional="true">($T15*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 15" Optional="true">($T16*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 16" Optional="true">($T17*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 17" Optional="true">($T18*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 18" Optional="true">($T19*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 19" Optional="true">($T20*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 20" Optional="true">($T21*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 21" Optional="true">($T22*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 22" Optional="true">($T23*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 23" Optional="true">($T24*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 24" Optional="true">($T25*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 25" Optional="true">($T26*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 26" Optional="true">($T27*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 27" Optional="true">($T28*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 28" Optional="true">($T29*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 29" Optional="true">($T30*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
<Item Name="[value]" Condition="index() == 30" Optional="true">($T31*)mStorage.mBuffer.mCharData</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<>">
|
|
||||||
<DisplayString IncludeView="noparens"></DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand/>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[2]">(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*,*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[2]">(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[3]">(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*,*,*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[2]">(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[3]">(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[4]">(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*,*,*,*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[2]">(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[3]">(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[4]">(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[5]">(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
<Type Name="eastl::tuple<*,*,*,*,*,*,*>">
|
|
||||||
<DisplayString IncludeView="noparens">{(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue}</DisplayString>
|
|
||||||
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
|
|
||||||
<Expand>
|
|
||||||
<Item Name="[0]">(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[1]">(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[2]">(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[3]">(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[4]">(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[5]">(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue</Item>
|
|
||||||
<Item Name="[6]">(*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue</Item>
|
|
||||||
</Expand>
|
|
||||||
</Type>
|
|
||||||
|
|
||||||
|
|
||||||
</AutoVisualizer>
|
|
||||||
44
conanfile.py
44
conanfile.py
@@ -5,13 +5,14 @@ import os
|
|||||||
|
|
||||||
required_conan_version = ">=1.33.0"
|
required_conan_version = ">=1.33.0"
|
||||||
|
|
||||||
class Bigfoot(ConanFile):
|
class Bin2CPP(ConanFile):
|
||||||
name = "bin2cpp"
|
name = "bin2cpp"
|
||||||
homepage = "https://git.romainboullard.com/rboullard/Bin2CPP"
|
homepage = "https://git.romainboullard.com/rboullard/Bin2CPP"
|
||||||
description = "A utility that converts files to CPP headers"
|
description = "A utility that converts files to CPP headers"
|
||||||
topics = ("utility")
|
topics = ("utility")
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
version = "0.1.0"
|
version = "1.0.0"
|
||||||
|
package_type = "application"
|
||||||
|
|
||||||
# Binary configuration
|
# Binary configuration
|
||||||
settings = "os", "compiler", "build_type", "arch"
|
settings = "os", "compiler", "build_type", "arch"
|
||||||
@@ -19,15 +20,24 @@ class Bigfoot(ConanFile):
|
|||||||
"shared": [True, False],
|
"shared": [True, False],
|
||||||
"fPIC": [True, False],
|
"fPIC": [True, False],
|
||||||
"build_tests": [True, False],
|
"build_tests": [True, False],
|
||||||
|
"asan": [True, False],
|
||||||
|
"coverage": [True, False]
|
||||||
}
|
}
|
||||||
default_options = {
|
default_options = {
|
||||||
"shared": False,
|
"shared": False,
|
||||||
"fPIC": True,
|
"fPIC": True,
|
||||||
"build_tests": False,
|
"build_tests": False,
|
||||||
|
"asan": False,
|
||||||
|
"coverage": False
|
||||||
}
|
}
|
||||||
|
|
||||||
generators = "CMakeDeps"
|
generators = "CMakeDeps"
|
||||||
|
|
||||||
|
def export_sources(self):
|
||||||
|
copy(self, "CMakeLists.txt", self.recipe_folder, self.export_sources_folder)
|
||||||
|
copy(self, os.path.join("Bin2CPP", "*"), self.recipe_folder, self.export_sources_folder)
|
||||||
|
copy(self, os.path.join("CMake", "*"), self.recipe_folder, self.export_sources_folder)
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
cmake_layout(self)
|
cmake_layout(self)
|
||||||
|
|
||||||
@@ -35,20 +45,16 @@ class Bigfoot(ConanFile):
|
|||||||
if self.settings.os == "Windows":
|
if self.settings.os == "Windows":
|
||||||
del self.options.fPIC
|
del self.options.fPIC
|
||||||
|
|
||||||
self.options['mimalloc'].override = True
|
if(self.options.asan):
|
||||||
self.options['mimalloc'].shared = True
|
self.options["mimalloc"].asan = True
|
||||||
if(self.settings.os == "Windows"):
|
|
||||||
self.options["mimalloc"].win_redirect = True
|
|
||||||
|
|
||||||
def requirements(self):
|
def requirements(self):
|
||||||
self.requires("quill/11.0.2", transitive_headers=True)
|
self.requires("quill/11.0.2", transitive_headers=True)
|
||||||
self.requires("eastl/3.27.01@bigfootdev/main", transitive_headers=True)
|
self.requires("magic_enum/0.9.7", transitive_headers=True)
|
||||||
self.requires("mimalloc/3.2.8@bigfootdev/main", transitive_headers=True)
|
self.requires("mimalloc/3.2.8@bigfootdev/main", transitive_headers=True)
|
||||||
self.requires("cli11/2.6.1@bigfootdev/main")
|
self.requires("cli11/2.6.1@bigfootdev/main")
|
||||||
self.requires("rapidhash/3.0@bigfootdev/main", transitive_headers=True)
|
|
||||||
|
|
||||||
if(self.settings.build_type == "RelWithDebInfo" or self.settings.build_type == "Debug"):
|
self.requires("cpptrace/1.0.4", transitive_headers=True)
|
||||||
self.requires("cpptrace/1.0.4", transitive_headers=True)
|
|
||||||
|
|
||||||
if(self.options.build_tests):
|
if(self.options.build_tests):
|
||||||
self.test_requires("gtest/1.17.0")
|
self.test_requires("gtest/1.17.0")
|
||||||
@@ -57,6 +63,8 @@ class Bigfoot(ConanFile):
|
|||||||
tc = CMakeToolchain(self)
|
tc = CMakeToolchain(self)
|
||||||
|
|
||||||
tc.variables["BUILD_TESTS"] = self.options.build_tests
|
tc.variables["BUILD_TESTS"] = self.options.build_tests
|
||||||
|
tc.variables["ASAN"] = self.options.asan
|
||||||
|
tc.variables["COVERAGE"] = self.options.coverage
|
||||||
|
|
||||||
tc.generate()
|
tc.generate()
|
||||||
|
|
||||||
@@ -64,3 +72,19 @@ class Bigfoot(ConanFile):
|
|||||||
cmake = CMake(self)
|
cmake = CMake(self)
|
||||||
cmake.configure()
|
cmake.configure()
|
||||||
cmake.build()
|
cmake.build()
|
||||||
|
|
||||||
|
def package(self):
|
||||||
|
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.install()
|
||||||
|
|
||||||
|
copy(self, "Bin2CPPTargets.cmake",
|
||||||
|
src=os.path.join(self.source_folder, "CMake"),
|
||||||
|
dst=os.path.join(self.package_folder, "bin"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _module_path(self):
|
||||||
|
return os.path.join("bin", "Bin2CPPTargets.cmake")
|
||||||
|
|
||||||
|
def package_info(self):
|
||||||
|
self.cpp_info.set_property("cmake_build_modules", [self._module_path])
|
||||||
0
generate_bin2cpp.sh
Normal file → Executable file
0
generate_bin2cpp.sh
Normal file → Executable file
@@ -22,12 +22,9 @@ if "%~1"=="force" (
|
|||||||
REM Add the remote
|
REM Add the remote
|
||||||
conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages
|
conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages
|
||||||
|
|
||||||
REM Install the conan configuration
|
|
||||||
conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git
|
|
||||||
|
|
||||||
REM Install dependencies with the specified build option
|
REM Install dependencies with the specified build option
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=Release -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/msvc -pr:b=./ConanProfiles/msvc %build_option% -of build -s build_type=Release
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/msvcd -pr:b=./ConanProfiles/msvcd %build_option% -of build -s build_type=RelWithDebInfo
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=Debug -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/msvcd -pr:b=./ConanProfiles/msvcd %build_option% -of build -s build_type=Debug
|
||||||
|
|
||||||
endlocal
|
endlocal
|
||||||
|
|||||||
16
generate_dependencies.sh
Normal file → Executable file
16
generate_dependencies.sh
Normal file → Executable file
@@ -9,18 +9,16 @@ fi
|
|||||||
# Add the remote
|
# Add the remote
|
||||||
conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages
|
conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages
|
||||||
|
|
||||||
# Install the conan configuration
|
|
||||||
conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git
|
|
||||||
|
|
||||||
# Set the build option based on the argument
|
# Set the build option based on the argument
|
||||||
if [ "$1" == "force" ]; then
|
if [ "$1" == "force" ]; then
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=Release -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clang -pr:b=./ConanProfiles/clang --build='*' -of build -s build_type=Release
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build='*' -of build -s build_type=RelWithDebInfo
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=Debug -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build='*' -of build -s build_type=Debug
|
||||||
elif [ "$1" == "missing" ]; then
|
elif [ "$1" == "missing" ]; then
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=Release -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clang -pr:b=./ConanProfiles/clang --build=missing -of build -s build_type=Release
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build=missing -of build -s build_type=RelWithDebInfo
|
||||||
conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=Debug -o bin2cpp/*:build_tests=True
|
conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build=missing -of build -s build_type=Debug
|
||||||
|
else
|
||||||
echo "Invalid argument: $1"
|
echo "Invalid argument: $1"
|
||||||
echo "Usage: $0 [force|missing]"
|
echo "Usage: $0 [force|missing]"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
7
test_package/CMakeLists.txt
Normal file
7
test_package/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
project(test_package LANGUAGES C)
|
||||||
|
|
||||||
|
find_package(Bin2CPP REQUIRED CONFIG)
|
||||||
|
|
||||||
|
find_program(BIN2CPP_EXECUTABLE NAMES Bin2CPP)
|
||||||
|
execute_process(COMMAND ${BIN2CPP_EXECUTABLE} -h)
|
||||||
18
test_package/conanfile.py
Normal file
18
test_package/conanfile.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from conan import ConanFile
|
||||||
|
from conan.tools.build import can_run
|
||||||
|
from conan.tools.cmake import CMake, cmake_layout
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class TestPackageConan(ConanFile):
|
||||||
|
settings = "os", "arch", "compiler", "build_type"
|
||||||
|
generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv"
|
||||||
|
|
||||||
|
def layout(self):
|
||||||
|
cmake_layout(self)
|
||||||
|
|
||||||
|
def requirements(self):
|
||||||
|
self.requires(self.tested_reference_str)
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
self.run("Bin2CPP --help", env="conanrun")
|
||||||
Reference in New Issue
Block a user