Compare commits

..

19 Commits

Author SHA1 Message Date
Emil Dotchevski
c1e7e3511e Serialization 2026-01-12 00:14:24 -05:00
Peter Dimov
95b1ead06c Merge pull request #57 from grafikrobot/modular
Add support for modular build structure.
2025-05-03 03:11:14 +03:00
Rene Rivera
e46dd22b3c Enable example that was commented out to get clean builds. 2025-05-02 18:00:06 -05:00
Rene Rivera
1da3782f79 Move project global include to target local include. 2025-04-07 11:32:37 -05:00
Rene Rivera
71ff2a5254 Sync from upstream. 2025-04-04 21:39:13 -05:00
Andrey Semashev
9238ef8e7f Avoid including deprecated atomic_count.hpp header. (#59)
boost/detail/atomic_count.hpp was moved into boost/smart_ptr/detail and
is now deprecated and emits warnings.
2025-03-01 16:25:20 -08:00
Emil Dotchevski
5ea93e34e1 gha update 2025-03-01 14:48:05 -08:00
Rene Rivera
40554e238c Fix lib build, re-enable some tests. 2024-08-14 23:22:20 -05:00
Rene Rivera
95854acc9a Update build deps. 2024-08-02 21:56:17 -05:00
Rene Rivera
b5bf79462e Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:22 -05:00
Rene Rivera
ec7442e3b7 Update copyright dates. 2024-07-20 22:52:03 -05:00
Rene Rivera
a27c2d5127 Bump B2 require to 5.2 2024-06-14 11:33:55 -05:00
Rene Rivera
64ca508153 Sync from upstream. 2024-06-02 13:49:17 -05:00
Peter Dimov
ece51fe0f7 Update ci.yml 2024-05-31 05:27:49 +03:00
Peter Dimov
399208b682 Make the library header-only in CMakeLists.txt 2024-05-31 04:48:39 +03:00
Rene Rivera
1c66828bb5 Add requires-b2 check to top-level build file. 2024-05-05 09:00:01 -05:00
Rene Rivera
fd72443067 Add missing NO_LIB usage requirements. 2024-04-28 20:15:04 -05:00
Rene Rivera
752185750d Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:15:58 -05:00
Rene Rivera
948578d5b4 Make the library modular usable. 2024-03-11 08:33:41 -05:00
20 changed files with 946 additions and 100 deletions

View File

@@ -18,165 +18,181 @@ jobs:
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-4.8-multilib
address-model: 32,64
install: g++-4.8
- toolset: gcc-5
cxxstd: "03,11,14,1z"
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-5-multilib
address-model: 32,64
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-6-multilib
address-model: 32,64
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-8-multilib
address-model: 32,64
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-10-multilib
address-model: 32,64
install: g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install: g++-11-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "03,11,14,17,20,2b"
cxxstd: "11,14,17,2a"
os: ubuntu-22.04
install: g++-12-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12
- toolset: gcc-13
cxxstd: "03,11,14,17,20,2b"
container: ubuntu:23.04
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
install: g++-13-multilib
address-model: 32,64
container: ubuntu:24.04
install: g++-13
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install: g++-14
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxstd: "11,14,17,20"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20,2b"
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "03,11,14,17,20,2b"
container: ubuntu:23.04
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "03,11,14,17,20,2b"
container: ubuntu:23.10
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-12
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.10
os: ubuntu-latest
install: clang-19
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-15
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
container:
image: ${{matrix.container}}
volumes:
- /node20217:/node20217:rw,rshared
- ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++
apt-get -y install sudo python3 git g++ curl xz-utils
- name: Install nodejs20glibc2.17
if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }}
run: |
curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz
tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
ldd /__e/node20/bin/node
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
@@ -203,6 +219,10 @@ jobs:
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
cd libs/throw_exception
git fetch origin feature/serialization
git checkout feature/serialization
cd ../..
./bootstrap.sh
./b2 -d0 headers
@@ -211,10 +231,15 @@ jobs:
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Download nlohmann/json
run: |
cd ../boost-root/libs/$LIBRARY
python3 scripts/download_nlohmann_json.py
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release exception-handling=on,off rtti=on,off link=static,shared visibility=hidden,global
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release exception-handling=on,off rtti=on,off link=static,shared visibility=hidden,global
windows:
strategy:
@@ -222,7 +247,7 @@ jobs:
matrix:
include:
- toolset: msvc-14.0
cxxstd: 14,latest
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
@@ -234,18 +259,18 @@ jobs:
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@@ -266,9 +291,19 @@ jobs:
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
cd libs\throw_exception
git fetch origin feature/serialization
git checkout feature/serialization
cd ..\..
cmd /c bootstrap
b2 -d0 headers
- name: Download nlohmann/json
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%
python3 scripts/download_nlohmann_json.py
- name: Run tests
shell: cmd
run: |

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/.vscode/ipch/*
/.vscode/settings.json
.DS_Store
/test/nlohmann/

101
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,101 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Download nlohmann/json.hpp",
"type": "shell",
"command": "python scripts/download_nlohmann_json.py",
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "b2: Run all tests (default)",
"type": "shell",
"dependsOn": ["Download nlohmann/json.hpp"],
"command": "../../b2 test",
"options": {
"cwd": "${workspaceFolder}"
},
"group": "test",
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceFolder}"]
},
"windows": {
"command": "..\\..\\b2 test",
"problemMatcher": {
"base": "$msCompile",
"fileLocation": ["relative", "${workspaceFolder}"]
}
}
},
{
"label": "b2: Run all tests (release)",
"type": "shell",
"dependsOn": ["Download nlohmann/json.hpp"],
"command": "../../b2 test variant=release",
"options": {
"cwd": "${workspaceFolder}"
},
"group": "test",
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceFolder}"]
},
"windows": {
"command": "..\\..\\b2 test variant=release",
"problemMatcher": {
"base": "$msCompile",
"fileLocation": ["relative", "${workspaceFolder}"]
}
}
},
{
"label": "b2: Run all tests (all configs)",
"type": "shell",
"dependsOn": ["Download nlohmann/json.hpp"],
"command": "../../b2 test exception-handling=on,off rtti=on,off variant=debug,release link=static,shared",
"options": {
"cwd": "${workspaceFolder}"
},
"group": "test",
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceFolder}"]
},
"windows": {
"command": "..\\..\\b2 test exception-handling=on,off rtti=on,off variant=debug,release link=static,shared",
"problemMatcher": {
"base": "$msCompile",
"fileLocation": ["relative", "${workspaceFolder}"]
}
}
},
{
"label": "b2: Run test for current editor file",
"type": "shell",
"dependsOn": ["Download nlohmann/json.hpp"],
"command": "../../b2 test ${fileBasenameNoExtension}.test",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceFolder}"]
},
"windows": {
"command": "..\\..\\b2 test ${fileBasenameNoExtension}.test",
"problemMatcher": {
"base": "$msCompile",
"fileLocation": ["relative", "${workspaceFolder}"]
}
}
}
]
}

View File

@@ -1,3 +1,4 @@
# Generated by `boostdep --cmake exception`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
@@ -6,16 +7,13 @@ cmake_minimum_required(VERSION 3.5...3.20)
project(boost_exception VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_exception STATIC
src/clone_current_exception_non_intrusive.cpp
)
add_library(boost_exception INTERFACE)
add_library(Boost::exception ALIAS boost_exception)
target_include_directories(boost_exception PUBLIC include)
target_include_directories(boost_exception INTERFACE include)
target_link_libraries(boost_exception
PUBLIC
INTERFACE
Boost::assert
Boost::config
Boost::core

27
build.jam Normal file
View File

@@ -0,0 +1,27 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/core//boost_core
/boost/smart_ptr//boost_smart_ptr
/boost/throw_exception//boost_throw_exception
/boost/tuple//boost_tuple
/boost/type_traits//boost_type_traits ;
project /boost/exception
;
explicit
[ alias boost_exception : build//boost_exception ]
[ alias all : boost_exception example test ]
;
call-if : boost-library exception
: install boost_exception
;

View File

@@ -5,10 +5,11 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project boost/exception
project
: source-location ../src
: common-requirements <include>../include <library>$(boost_dependencies)
: requirements <link>static
: usage-requirements <define>BOOST_EXCEPTION_NO_LIB=1
;
lib boost_exception : clone_current_exception_non_intrusive.cpp ;
boost-install boost_exception ;
lib boost_exception : clone_current_exception_non_intrusive.cpp : <exception-handling>on ;

View File

@@ -5,11 +5,13 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements <library>/boost/exception//boost_exception ;
exe example_io : example_io.cpp ;
obj error_info_1 : error_info_1.cpp ;
obj error_info_2 : error_info_2.cpp ;
obj cloning_1 : cloning_1.cpp ;
obj cloning_2 : cloning_2.cpp : <threading>multi ;
obj cloning_2 : cloning_2.cpp /boost/thread//boost_thread : <threading>multi ;
obj info_tuple : info_tuple.cpp ;
obj enable_error_info : enable_error_info.cpp ;
obj logging : logging.cpp ;

View File

@@ -13,6 +13,8 @@
#include <utility>
#include <string>
namespace boost { namespace exception_detail { class writer; } }
#ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
#if defined(__GNUC__) && __GNUC__*100+__GNUC_MINOR__>301
#pragma GCC system_header
@@ -38,6 +40,7 @@ boost
virtual std::string name_value_string() const = 0;
virtual error_info_base * clone() const = 0;
virtual void write_to(writer &) const = 0;
virtual
~error_info_base() BOOST_NOEXCEPT_OR_NOTHROW
@@ -97,6 +100,7 @@ boost
error_info & operator=( error_info && x );
#endif
std::string name_value_string() const;
void write_to(exception_detail::writer &) const;
value_type v_;
};
}

View File

@@ -21,4 +21,4 @@ BOOST_PRAGMA_MESSAGE("C++03 support was deprecated in Boost.Exception 1.85 and w
#endif
#endif
#endif

View File

@@ -11,7 +11,17 @@
#include <boost/core/demangle.hpp>
#include <boost/current_function.hpp>
#include <string>
#include <string.h>
#include <ostream>
#include <cstring>
#include <cstddef>
#ifndef BOOST_EXCEPTION_PRETTY_FUNCTION
# if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
# define BOOST_EXCEPTION_PRETTY_FUNCTION __FUNCSIG__
# else
# define BOOST_EXCEPTION_PRETTY_FUNCTION __PRETTY_FUNCTION__
# endif
#endif
#ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
#if defined(__GNUC__) && __GNUC__*100+__GNUC_MINOR__>301
@@ -73,6 +83,206 @@ boost
return a.type_!=b.type_ && strcmp(a.type_->name(), b.type_->name()) < 0;
}
};
template <int S1, int S2, int I, bool = (S1 >= S2)>
struct
cpp11_prefix
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&)[S1], char const (&)[S2]) noexcept
{
return false;
}
};
template <int S1, int S2, int I>
struct
cpp11_prefix<S1, S2, I, true>
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
{
return str[I] == prefix[I] && cpp11_prefix<S1, S2, I - 1>::check(str, prefix);
}
};
template <int S1, int S2>
struct
cpp11_prefix<S1, S2, 0, true>
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
{
return str[0] == prefix[0];
}
};
template <int S1, int S2>
BOOST_FORCEINLINE constexpr
int
check_prefix(char const (&str)[S1], char const (&prefix)[S2]) noexcept
{
return cpp11_prefix<S1, S2, S2 - 2>::check(str, prefix) ? S2 - 1 : 0;
}
template <int S1, int S2, int I1, int I2, bool = (S1 >= S2)>
struct
cpp11_suffix
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&)[S1], char const (&)[S2]) noexcept
{
return false;
}
};
template <int S1, int S2, int I1, int I2>
struct
cpp11_suffix<S1, S2, I1, I2, true>
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
{
return str[I1] == suffix[I2] && cpp11_suffix<S1, S2, I1 - 1, I2 - 1>::check(str, suffix);
}
};
template <int S1, int S2, int I1>
struct
cpp11_suffix<S1, S2, I1, 0, true>
{
BOOST_FORCEINLINE static constexpr
bool
check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
{
return str[I1] == suffix[0];
}
};
template <int S1, int S2>
BOOST_FORCEINLINE constexpr
int
check_suffix(char const (&str)[S1], char const (&suffix)[S2]) noexcept
{
return cpp11_suffix<S1, S2, S1 - 2, S2 - 2>::check(str, suffix) ? S1 - S2 : 0;
}
}
namespace
n
{
struct
r
{
char const * name_not_zero_terminated_at_length;
std::size_t length;
};
#ifdef _MSC_VER
# define BOOST_EXCEPTION_CDECL __cdecl
#else
# define BOOST_EXCEPTION_CDECL
#endif
template <class T>
BOOST_FORCEINLINE
r
BOOST_EXCEPTION_CDECL
p()
{
#define BOOST_EXCEPTION_P(P) (sizeof(char[1 + exception_detail::check_prefix(BOOST_EXCEPTION_PRETTY_FUNCTION, P)]) - 1)
// clang style:
std::size_t const p01 = BOOST_EXCEPTION_P("r boost::n::p() [T = ");
std::size_t const p02 = BOOST_EXCEPTION_P("r __cdecl boost::n::p(void) [T = ");
// old clang style:
std::size_t const p03 = BOOST_EXCEPTION_P("boost::n::r boost::n::p() [T = ");
std::size_t const p04 = BOOST_EXCEPTION_P("boost::n::r __cdecl boost::n::p(void) [T = ");
// gcc style:
std::size_t const p05 = BOOST_EXCEPTION_P("boost::n::r boost::n::p() [with T = ");
std::size_t const p06 = BOOST_EXCEPTION_P("boost::n::r __cdecl boost::n::p() [with T = ");
// msvc style, struct:
std::size_t const p07 = BOOST_EXCEPTION_P("struct boost::n::r __cdecl boost::n::p<struct ");
// msvc style, class:
std::size_t const p08 = BOOST_EXCEPTION_P("struct boost::n::r __cdecl boost::n::p<class ");
// msvc style, enum:
std::size_t const p09 = BOOST_EXCEPTION_P("struct boost::n::r __cdecl boost::n::p<enum ");
// msvc style, built-in type:
std::size_t const p10 = BOOST_EXCEPTION_P("struct boost::n::r __cdecl boost::n::p<");
#undef BOOST_EXCEPTION_P
#define BOOST_EXCEPTION_S(S) (sizeof(char[1 + exception_detail::check_suffix(BOOST_EXCEPTION_PRETTY_FUNCTION, S)]) - 1)
// clang/gcc style:
std::size_t const s01 = BOOST_EXCEPTION_S("]");
// msvc style:
std::size_t const s02 = BOOST_EXCEPTION_S(">(void)");
#undef BOOST_EXCEPTION_S
char static_assert_unrecognized_pretty_function_format_please_file_github_issue[sizeof(
char[
(s01 && (1 == (!!p01 + !!p02 + !!p03 + !!p04 + !!p05 + !!p06)))
||
(s02 && (1 == (!!p07 + !!p08 + !!p09)))
||
(s02 && !!p10)
]
) * 2 - 1];
(void) static_assert_unrecognized_pretty_function_format_please_file_github_issue;
if( std::size_t const p = sizeof(char[1 + !!s01 * (p01 + p02 + p03 + p04 + p05 + p06)]) - 1 )
return { BOOST_EXCEPTION_PRETTY_FUNCTION + p, s01 - p };
if( std::size_t const p = sizeof(char[1 + !!s02 * (p07 + p08 + p09)]) - 1 )
return { BOOST_EXCEPTION_PRETTY_FUNCTION + p, s02 - p };
std::size_t const p = sizeof(char[1 + !!s02 * p10]) - 1;
return { BOOST_EXCEPTION_PRETTY_FUNCTION + p, s02 - p };
}
#undef BOOST_EXCEPTION_CDECL
}
namespace
exception_detail
{
struct
pretty_type_name
{
char const * name_not_zero_terminated_at_length;
std::size_t length;
template <class CharT, class Traits>
friend
std::basic_ostream<CharT, Traits> &
operator<<(std::basic_ostream<CharT, Traits> & os, pretty_type_name const & x)
{
return os.write(x.name_not_zero_terminated_at_length, x.length);
}
template <std::size_t S>
friend
char *
to_zstr(char (&zstr)[S], pretty_type_name const & x) noexcept
{
std::size_t n = x.length < S - 1 ? x.length : S - 1;
std::memcpy(zstr, x.name_not_zero_terminated_at_length, n);
zstr[n] = 0;
return zstr;
}
};
template <class T>
pretty_type_name
get_pretty_tag_type_name()
{
n::r parsed = n::p<T>();
return { parsed.name_not_zero_terminated_at_length, parsed.length };
}
}
}

View File

@@ -0,0 +1,114 @@
//Copyright (c) 2006-2026 Emil Dotchevski and Reverge Studios, Inc.
//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_EXCEPTION_DETAIL_WRITER_HPP_INCLUDED
#define BOOST_EXCEPTION_DETAIL_WRITER_HPP_INCLUDED
#include <boost/exception/detail/type_info.hpp>
#include <type_traits>
#include <utility>
namespace
boost
{
template <class Tag, class T> class error_info;
namespace
exception_serialization
{
struct writer_adl {};
}
namespace
exception_detail
{
template <class T>
struct first_arg;
template <class C, class R, class A1, class... A>
struct
first_arg<R(C::*)(A1, A...)>
{
using type = A1;
};
template <class C, class R, class A1, class... A>
struct
first_arg<R(C::*)(A1, A...) const>
{
using type = A1;
};
class
writer:
exception_serialization::writer_adl
{
writer(writer const &) = delete;
writer & operator=(writer const &) = delete;
core::typeinfo const * type_;
void * w_;
bool
dispatch_()
{
return false;
}
template <class F1, class... Fn>
bool
dispatch_(F1 && f1, Fn && ... fn)
{
using writer_type = typename std::decay<typename first_arg<decltype(&std::decay<F1>::type::operator())>::type>::type;
if (writer_type * w = get<writer_type>())
{
std::forward<F1>(f1)(*w);
return true;
}
return dispatch_(std::forward<Fn>(fn)...);
}
protected:
template <class Writer>
explicit
writer(Writer * w) noexcept:
type_(&BOOST_CORE_TYPEID(Writer)),
w_(w)
{
}
public:
template <class Writer>
Writer *
get() noexcept
{
return *type_ == BOOST_CORE_TYPEID(Writer) ? static_cast<Writer *>(w_) : nullptr;
}
template <class... Fn>
bool
dispatch(Fn && ... fn)
{
return dispatch_(std::forward<Fn>(fn)...);
}
};
template <class Writer>
struct
writer_adaptor:
writer
{
explicit
writer_adaptor(Writer & w) noexcept:
writer(&w)
{
}
};
}
}
#endif

View File

@@ -205,6 +205,65 @@ boost
#endif
return w;
}
namespace
exception_detail
{
template <class Writer>
void
write_diagnostic_information_to_impl_( boost::exception const * be, std::exception const * se, Writer & w )
{
if( !be && !se )
return;
#ifndef BOOST_NO_RTTI
if( !be )
be=dynamic_cast<boost::exception const *>(se);
if( !se )
se=dynamic_cast<std::exception const *>(be);
#endif
if( be )
{
if( char const * const * f=get_error_info<throw_file>(*be) )
write_nested(w, *f, "throw_file");
if( int const * l=get_error_info<throw_line>(*be) )
write_nested(w, *l, "throw_line");
if( char const * const * fn=get_error_info<throw_function>(*be) )
write_nested(w, *fn, "throw_function");
}
#ifndef BOOST_NO_RTTI
if( be || se )
write_nested(w, core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()).c_str(), "dynamic_exception_type");
#endif
if( se )
if( char const * wh = se->what() )
write_nested(w, wh, "std::exception::what");
if( be )
if( error_info_container * c = be->data_.get() )
{
writer_adaptor<Writer> wa(w);
c->write_to(wa);
}
}
}
template <class T, class Writer>
void
write_diagnostic_information_to( T const & e, Writer & w )
{
exception_detail::write_diagnostic_information_to_impl_(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),w);
}
#ifndef BOOST_NO_EXCEPTIONS
template <class Writer>
void
write_current_exception_diagnostic_information_to( Writer & w )
{
boost::exception const * be=current_exception_cast<boost::exception const>();
std::exception const * se=current_exception_cast<std::exception const>();
if( be || se )
exception_detail::write_diagnostic_information_to_impl_(be,se,w);
}
#endif
}
#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)

View File

@@ -11,7 +11,9 @@
#include <boost/exception/to_string_stub.hpp>
#include <boost/exception/detail/error_info_impl.hpp>
#include <boost/exception/detail/shared_ptr.hpp>
#include <boost/exception/detail/writer.hpp>
#include <map>
#include <type_traits>
#ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
#if defined(__GNUC__) && __GNUC__*100+__GNUC_MINOR__>301
@@ -28,6 +30,36 @@
namespace
boost
{
namespace
exception_serialization
{
template <class Writer, class T, class... Unused>
typename std::enable_if<std::is_base_of<exception_detail::writer, Writer>::value>::type
serialize(Writer &, T const &, char const *, Unused && ...)
{
}
template <class Writer, class Tag, class T>
void
write(Writer & w, error_info<Tag, T> const & e)
{
write(w, e.value());
}
}
namespace
exception_detail
{
template <class Tag, class T>
void
serialize_(writer & w, error_info<Tag,T> const & x)
{
using namespace boost::exception_serialization;
char buf[256];
serialize(w, x.value(), to_zstr(buf, get_pretty_tag_type_name<Tag>()));
}
}
template <class Tag,class T>
inline
std::string
@@ -53,6 +85,15 @@ boost
return to_string_stub(*this);
}
template <class Tag,class T>
inline
void
error_info<Tag,T>::
write_to(exception_detail::writer & w) const
{
exception_detail::serialize_(w, *this);
}
namespace
exception_detail
{
@@ -108,6 +149,16 @@ boost
return diagnostic_info_str_.c_str();
}
void
write_to( writer & w ) const
{
for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
{
error_info_base const & x = *i->second;
x.write_to(w);
}
}
private:
friend class boost::exception;

View File

@@ -0,0 +1,43 @@
//Copyright (c) 2006-2026 Emil Dotchevski and Reverge Studios, Inc.
//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_EXCEPTION_SERIALIZATION_NLOHMANN_WRITER_HPP_INCLUDED
#define BOOST_EXCEPTION_SERIALIZATION_NLOHMANN_WRITER_HPP_INCLUDED
#include <utility>
namespace
boost
{
namespace
exception_serialization
{
template <class Json>
struct
nlohmann_writer
{
Json & j_;
template <class T>
friend
auto
write(nlohmann_writer & w, T const & x) -> decltype(to_json(std::declval<Json &>(), x))
{
to_json(w.j_, x);
}
template <class T>
friend
void
write_nested(nlohmann_writer & w, T const & x, char const * name)
{
nlohmann_writer nested{w.j_[name]};
write(nested, x);
}
};
}
}
#endif

View File

@@ -0,0 +1,33 @@
"""
Copyright 2018-2026 Emil Dotchevski and Reverge Studios, Inc.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This program downloads the nlohmann/json single header distribution.
Usage:
python3 download_nlohmann_json.py
"""
import urllib.request
import os
url = "https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp"
output_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "test", "nlohmann")
output_file = os.path.join(output_dir, "json.hpp")
def _main():
if os.path.exists(output_file):
print(f"{output_file} already exists, skipping download")
return
os.makedirs(output_dir, exist_ok=True)
print(f"Downloading {url}...")
urllib.request.urlretrieve(url, output_file)
print(f"Saved to {output_file}")
if __name__ == "__main__":
_main()

View File

@@ -7,6 +7,8 @@
import testing ;
project : requirements <library>/boost/exception//boost_exception ;
#to_string
run is_output_streamable_test.cpp ;
@@ -22,7 +24,7 @@ run 2-throw_exception_no_exceptions_test.cpp : : : <exception-handling>off ;
run 3-throw_exception_no_integration_test.cpp : : : <exception-handling>on ;
run 4-throw_exception_no_both_test.cpp : : : <exception-handling>off ;
run cloning_test.cpp : : : <exception-handling>on ;
run copy_exception_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi <exception-handling>on ;
run copy_exception_test.cpp ../../thread/src/tss_null.cpp /boost/thread//boost_thread : : : <threading>multi <exception-handling>on ;
run copy_exception_no_exceptions_test.cpp : : : <exception-handling>off <rtti>on ;
run unknown_exception_test.cpp : : : <exception-handling>on ;
run exception_test.cpp : : : <exception-handling>on ;
@@ -39,8 +41,9 @@ run refcount_ptr_test.cpp ;
run current_exception_cast_test.cpp : : : <exception-handling>on ;
run no_exceptions_test.cpp : : : <exception-handling>off ;
run errinfos_test.cpp : : : <exception-handling>on ;
run exception_ptr_test.cpp/<define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : <threading>multi <exception-handling>on : non_intrusive_exception_ptr_test ;
run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi <exception-handling>on ;
run nlohmann_test.cpp : : : <exception-handling>on ;
run exception_ptr_test.cpp/<define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception//boost_exception /boost/thread//boost_thread : : : <threading>multi <exception-handling>on : non_intrusive_exception_ptr_test ;
run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost/thread//boost_thread : : : <threading>multi <exception-handling>on ;
run exception_ptr_test2.cpp ;
lib visibility_test_lib : visibility_test_lib.cpp : <visibility>hidden <exception-handling>on ;

View File

@@ -12,7 +12,7 @@
#include <boost/exception_ptr.hpp>
#include <boost/exception/get_error_info.hpp>
#include <boost/thread.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
typedef boost::error_info<struct tag_answer,int> answer;

View File

@@ -13,6 +13,7 @@
#include <boost/exception/info.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/detail/workaround.hpp>
#include <iostream>
#if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x610))
struct test_tag1 {};
@@ -141,9 +142,11 @@ main()
catch(
error1 & x )
{
std::string di1=boost::diagnostic_information(x);
std::string di1 = diagnostic_information(x);
std::cout << __LINE__ << " ------------------\n" << di1;
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = diagnostic_information(x);
std::cout << "\n" << di2 << std::endl;
test1(di1,di2);
}
try
@@ -155,9 +158,11 @@ main()
catch(
error1 & x )
{
std::string di1=boost::current_exception_diagnostic_information();
std::string di1 = current_exception_diagnostic_information();
std::cout << __LINE__ << " ------------------\n" << di1;
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = current_exception_diagnostic_information();
std::cout << "\n" << di2 << std::endl;
test1(di1,di2);
}
try
@@ -170,8 +175,10 @@ main()
error2 & x )
{
std::string di1 = diagnostic_information(x);
std::cout << __LINE__ << " ------------------\n" << di1;
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = diagnostic_information(x);
std::cout << "\n" << di2 << std::endl;
test2(di1,di2);
}
try
@@ -184,23 +191,27 @@ main()
error2 & x )
{
std::string di1 = current_exception_diagnostic_information();
BOOST_TEST(di1==boost::diagnostic_information_what(x));
std::cout << __LINE__ << " ------------------\n" << di1;
BOOST_TEST(di1 == diagnostic_information_what(x));
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = current_exception_diagnostic_information();
BOOST_TEST(di2==boost::diagnostic_information_what(x));
std::cout << "\n" << di2 << std::endl;
BOOST_TEST(di2 == diagnostic_information_what(x));
test2(di1,di2);
}
try
{
error3 x;
std::string di=diagnostic_information(x);
std::string di = diagnostic_information(x);
std::cout << __LINE__ << " ------------------\n" << di << std::endl;
test3(di);
throw x;
}
catch(
... )
{
std::string di=current_exception_diagnostic_information();
std::string di = current_exception_diagnostic_information();
std::cout << __LINE__ << " ------------------\n" << di << std::endl;
test3(di);
}
try
@@ -210,9 +221,10 @@ main()
catch(
error4 & x )
{
std::string di1=boost::diagnostic_information(x);
std::string wh1=x.what();
BOOST_TEST(wh1==di1);
std::string di1 = diagnostic_information(x);
std::cout << __LINE__ << " ------------------\n" << di1 << std::endl;
std::string wh1 = x.what();
BOOST_TEST(wh1 == di1);
}
try
{
@@ -222,13 +234,15 @@ main()
catch(
error4 & x )
{
std::string di1=boost::diagnostic_information(x);
std::string wh1=x.what();
BOOST_TEST(wh1==di1);
std::string di1 = diagnostic_information(x);
std::cout << __LINE__ << " ------------------\n" << di1;
std::string wh1 = x.what();
BOOST_TEST(wh1 == di1);
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = diagnostic_information(x);
std::string wh2=x.what();
BOOST_TEST(wh2==di2);
std::cout << "\n" << di2 << std::endl;
std::string wh2 = x.what();
BOOST_TEST(wh2 == di2);
test4(di1,di2);
}
try
@@ -239,13 +253,15 @@ main()
catch(
error4 & x )
{
std::string di1=boost::current_exception_diagnostic_information();
std::string wh1=x.what();
BOOST_TEST(wh1==di1);
std::string di1 = current_exception_diagnostic_information();
std::cout << __LINE__ << " ------------------\n" << di1;
std::string wh1 = x.what();
BOOST_TEST(wh1 == di1);
x << tagged_int1(2) << tagged_int2(2);
std::string di2 = current_exception_diagnostic_information();
std::string wh2=x.what();
BOOST_TEST(wh2==di2);
std::cout << "\n" << di2 << std::endl;
std::string wh2 = x.what();
BOOST_TEST(wh2 == di2);
test4(di1,di2);
}
return boost::report_errors();

View File

@@ -16,7 +16,7 @@
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>

148
test/nlohmann_test.cpp Normal file
View File

@@ -0,0 +1,148 @@
//Copyright (c) 2006-2026 Emil Dotchevski and Reverge Studios, Inc.
//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined( BOOST_NO_EXCEPTIONS )
# error This program requires exception handling.
#endif
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/serialization/nlohmann_writer.hpp>
#include <boost/throw_exception.hpp>
#include "nlohmann/json.hpp"
#include <boost/detail/lightweight_test.hpp>
#include <iomanip>
#include <iostream>
#include <exception>
using output_writer = boost::exception_serialization::nlohmann_writer<nlohmann::ordered_json>;
namespace boost { namespace exception_serialization {
template <class Handle, class E>
void
serialize(Handle & h, E const & e, char const * name)
{
h.dispatch(
[&](nlohmann_writer<nlohmann::json> & w) { write_nested(w, e, name); },
[&](nlohmann_writer<nlohmann::ordered_json> & w) { write_nested(w, e, name); }
);
}
} }
struct my_error_tag1;
struct my_error_tag2;
typedef boost::error_info<my_error_tag1, int> my_error1;
typedef boost::error_info<my_error_tag2, std::string> my_error2;
struct
my_info
{
int code;
char const * message;
template <class Json>
friend
void
to_json(Json & j, my_info const & e)
{
j["code"] = e.code;
j["message"] = e.message;
}
};
struct my_info_tag;
typedef boost::error_info<my_info_tag, my_info> my_error3;
struct
test_exception:
virtual boost::exception,
virtual std::exception
{
char const *
what() const noexcept override
{
return "test_exception::what";
}
};
void
check_output(nlohmann::ordered_json const & j, bool has_source_location)
{
if( has_source_location )
{
BOOST_TEST(j.contains("throw_file"));
BOOST_TEST(j.contains("throw_line"));
BOOST_TEST(j.contains("throw_function"));
}
#ifndef BOOST_NO_RTTI
BOOST_TEST(j.contains("dynamic_exception_type"));
#endif
BOOST_TEST(j.contains("std::exception::what"));
BOOST_TEST_EQ(j["std::exception::what"].get<std::string>(), "test_exception::what");
BOOST_TEST(j.contains("my_error_tag1"));
BOOST_TEST_EQ(j["my_error_tag1"].get<int>(), 42);
BOOST_TEST(j.contains("my_error_tag2"));
BOOST_TEST_EQ(j["my_error_tag2"].get<std::string>(), "hello");
BOOST_TEST(j.contains("my_info_tag"));
auto const & mij = j["my_info_tag"];
BOOST_TEST_EQ(mij["code"].get<int>(), 1);
BOOST_TEST_EQ(mij["message"].get<std::string>(), "error one");
}
int
main()
{
{
std::cout << "Testing write_diagnostic_information_to:\n";
nlohmann::ordered_json j;
try
{
test_exception e;
e <<
my_error1(42) <<
my_error2("hello") <<
my_error3({1, "error one"});
BOOST_THROW_EXCEPTION(e);
}
catch( test_exception & e )
{
output_writer w{j};
boost::write_diagnostic_information_to(e, w);
}
std::cout << std::setw(2) << j << std::endl;
check_output(j, true);
}
{
std::cout << "\nTesting write_current_exception_diagnostic_information_to:\n";
nlohmann::ordered_json j;
try
{
test_exception e;
e <<
my_error1(42) <<
my_error2("hello") <<
my_error3({1, "error one"});
BOOST_THROW_EXCEPTION(e);
}
catch( ... )
{
output_writer w{j};
boost::write_current_exception_diagnostic_information_to(w);
}
std::cout << std::setw(2) << j << std::endl;
check_output(j, true);
}
return boost::report_errors();
}