forked from boostorg/throw_exception
Compare commits
15 Commits
boost-1.78
...
develop
Author | SHA1 | Date | |
---|---|---|---|
f2b7655016 | |||
68d092f4d7 | |||
26f3ce3c5c | |||
e14f6ed69e | |||
3c67fc2b54 | |||
cffa8cd68c | |||
8608fdd923 | |||
b3a7f8e178 | |||
3e51d32285 | |||
f2ca8df9ab | |||
3470506880 | |||
c5dfcc3dd4 | |||
7b314a2184 | |||
dbbbb71232 | |||
d0f136e079 |
281
.drone.jsonnet
Normal file
281
.drone.jsonnet
Normal file
@ -0,0 +1,281 @@
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
local library = "throw_exception";
|
||||
|
||||
local triggers =
|
||||
{
|
||||
branch: [ "master", "develop", "feature/*" ]
|
||||
};
|
||||
|
||||
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
|
||||
local asan = { ASAN: '1' };
|
||||
|
||||
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "linux",
|
||||
arch: arch
|
||||
},
|
||||
steps:
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "exec",
|
||||
trigger: triggers,
|
||||
platform: {
|
||||
"os": "darwin",
|
||||
"arch": arch
|
||||
},
|
||||
node: {
|
||||
"os": osx_version
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
name: "everything",
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "windows",
|
||||
arch: arch
|
||||
},
|
||||
"steps":
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.4",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x' },
|
||||
"g++-4.4",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.6",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x' },
|
||||
"g++-4.6",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.7",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x' },
|
||||
"g++-4.7",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.8*",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.9",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11' },
|
||||
"g++-4.9",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 5*",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 6",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14' },
|
||||
"g++-6",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 7* 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 8",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11,14,17' },
|
||||
"g++-8",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* 32",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* 64",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 ARM64 32/64",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 10 32 ASAN",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '32' } + asan,
|
||||
"g++-10-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 10 64 ASAN",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '64' } + asan,
|
||||
"g++-10-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.5",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '03,11' },
|
||||
"clang-3.5",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.6",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '03,11,14' },
|
||||
"clang-3.6",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.7",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '03,11,14' },
|
||||
"clang-3.7",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.8",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '03,11,14' },
|
||||
"clang-3.8",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 13",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' },
|
||||
"clang-13",
|
||||
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 14 UBSAN",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + ubsan,
|
||||
"clang-14",
|
||||
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main"],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 14 ASAN",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + asan,
|
||||
"clang-14",
|
||||
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main"],
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2015 msvc-14.0",
|
||||
"cppalliance/dronevs2015",
|
||||
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2017 msvc-14.1",
|
||||
"cppalliance/dronevs2017",
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
]
|
23
.drone/drone.bat
Normal file
23
.drone/drone.bat
Normal file
@ -0,0 +1,23 @@
|
||||
@REM Copyright 2022 Peter Dimov
|
||||
@REM Distributed under the Boost Software License, Version 1.0.
|
||||
@REM https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ECHO ON
|
||||
|
||||
set LIBRARY=%1
|
||||
set DRONE_BUILD_DIR=%CD%
|
||||
|
||||
set BOOST_BRANCH=develop
|
||||
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
|
||||
python tools/boostdep/depinst/depinst.py %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
24
.drone/drone.sh
Executable file
24
.drone/drone.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@ -147,15 +147,23 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.0
|
||||
cxxstd: "14,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.1
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2016
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,latest"
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
@ -195,4 +203,4 @@ jobs:
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2019 Peter Dimov
|
||||
Copyright 2019, 2022 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
@ -10,6 +10,11 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Changes in 1.79.0
|
||||
|
||||
* Added `boost::throw_with_location`, a more lightweight alternative of
|
||||
`BOOST_THROW_EXCEPTION` for programs that do not use Boost.Exception.
|
||||
|
||||
## Changes in 1.73.0
|
||||
|
||||
* Added an overload of `throw_exception` that takes a `boost::source_location`
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2019 Peter Dimov
|
||||
Copyright 2019, 2022 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
@ -35,83 +35,16 @@ The macro `BOOST_THROW_EXCEPTION(x)` expands to
|
||||
`::boost::throw_exception(x, BOOST_CURRENT_LOCATION)`, passing the current source
|
||||
location.
|
||||
|
||||
[#examples]
|
||||
# Examples
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
When integration with Boost.Exception and `boost::exception_ptr` is not needed,
|
||||
the function `boost::throw_with_location` can be used instead. It also throws
|
||||
a user-provided exception, associating it with a supplied or inferred source
|
||||
location, but does not supply the `boost::exception` base class and does not
|
||||
enable `boost::exception_ptr` support.
|
||||
|
||||
## Using BOOST_THROW_EXCEPTION
|
||||
The source location of the exception thrown by `boost::throw_with_location`
|
||||
can be retrieved, after `catch(std::exception const & x)`, by using
|
||||
`boost::get_throw_location(x)`.
|
||||
|
||||
```
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
void f()
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( std::runtime_error( "Unspecified runtime error" ) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
std::cerr << boost::diagnostic_information( x ) << std::endl;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Using boost::throw_exception with a source location
|
||||
|
||||
```
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <stdexcept>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
void throw_index_error( std::size_t i, std::size_t n,
|
||||
boost::source_location const & loc )
|
||||
{
|
||||
std::string msg = "Index out of range: "
|
||||
+ boost::lexical_cast<std::string>( i ) + " >= "
|
||||
+ boost::lexical_cast<std::string>( n );
|
||||
|
||||
boost::throw_exception( std::out_of_range( msg ), loc );
|
||||
}
|
||||
|
||||
void f1( std::size_t i, std::size_t n )
|
||||
{
|
||||
if( i >= n )
|
||||
{
|
||||
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
|
||||
}
|
||||
}
|
||||
|
||||
void f2( std::size_t i, std::size_t n )
|
||||
{
|
||||
if( i >= n )
|
||||
{
|
||||
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
f1( 4, 3 );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
std::cerr << boost::diagnostic_information( x ) << std::endl;
|
||||
}
|
||||
}
|
||||
```
|
||||
`boost::get_throw_location` also works for exceptions thrown by the two argument
|
||||
overload of `boost::throw_exception`, or by `BOOST_THROW_EXCEPTION`; in this case
|
||||
it returns the source location stored in the `boost::exception` base class.
|
||||
|
218
doc/examples.adoc
Normal file
218
doc/examples.adoc
Normal file
@ -0,0 +1,218 @@
|
||||
////
|
||||
Copyright 2019, 2022 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#examples]
|
||||
# Examples
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Using BOOST_THROW_EXCEPTION
|
||||
|
||||
Demonstrates the use of `BOOST_THROW_EXCEPTION`.
|
||||
|
||||
[source,c++,linenums,highlight=8]
|
||||
----
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
void f()
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( std::runtime_error( "Unspecified runtime error" ) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
std::cerr << boost::diagnostic_information( x ) << std::endl;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Sample output:
|
||||
|
||||
```none
|
||||
example.cpp(8): Throw in function void f()
|
||||
Dynamic exception type: boost::wrapexcept<std::runtime_error>
|
||||
std::exception::what: Unspecified runtime error
|
||||
```
|
||||
|
||||
## Using boost::throw_exception with a source location
|
||||
|
||||
Demonstrates moving the call to `boost::throw_exception` to a common
|
||||
helper function that can be marked `BOOST_NOINLINE` to avoid
|
||||
unnecessary code duplication. The source location is passed
|
||||
explicitly to the helper function so that it can still record the
|
||||
logical throw point, instead of always pointing into the helper.
|
||||
|
||||
[source,c++,linenums,highlight=31]
|
||||
----
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/core/verbose_terminate_handler.hpp>
|
||||
#include <stdexcept>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
BOOST_NORETURN BOOST_NOINLINE
|
||||
void throw_index_error( std::size_t i, std::size_t n,
|
||||
boost::source_location const & loc )
|
||||
{
|
||||
std::string msg = "Index out of range: "
|
||||
+ boost::lexical_cast<std::string>( i ) + " >= "
|
||||
+ boost::lexical_cast<std::string>( n );
|
||||
|
||||
boost::throw_exception( std::out_of_range( msg ), loc );
|
||||
}
|
||||
|
||||
void f1( std::size_t i, std::size_t n )
|
||||
{
|
||||
if( i >= n )
|
||||
{
|
||||
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
|
||||
}
|
||||
}
|
||||
|
||||
void f2( std::size_t i, std::size_t n )
|
||||
{
|
||||
if( i >= n )
|
||||
{
|
||||
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
|
||||
f1( 0, 3 );
|
||||
f2( 4, 3 );
|
||||
}
|
||||
----
|
||||
|
||||
Sample output:
|
||||
|
||||
```none
|
||||
std::terminate called after throwing an exception:
|
||||
|
||||
type: boost::wrapexcept<std::out_of_range>
|
||||
what(): Index out of range: 4 >= 3
|
||||
location: <source>:31:34 in function 'f2'
|
||||
```
|
||||
|
||||
## Using boost::throw_with_location
|
||||
|
||||
This example demonstrates a trivial use of `boost::throw_with_location`. Since
|
||||
a source location is not supplied, the location of the call to
|
||||
`boost::throw_with_location` is implicitly captured.
|
||||
|
||||
[source,c++,linenums,highlight=9]
|
||||
----
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/verbose_terminate_handler.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
int f1( int x )
|
||||
{
|
||||
if( x < 0 )
|
||||
{
|
||||
boost::throw_with_location(
|
||||
std::invalid_argument( "f1: x cannot be negative" ) );
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
|
||||
return f1( -4 );
|
||||
}
|
||||
----
|
||||
|
||||
Sample output:
|
||||
|
||||
```none
|
||||
std::terminate called after throwing an exception:
|
||||
|
||||
type: boost::detail::with_throw_location<std::invalid_argument>
|
||||
what(): f1: x cannot be negative
|
||||
location: <source>:9:9 in function 'f1'
|
||||
```
|
||||
|
||||
## Using boost::throw_with_location with an explicit source location
|
||||
|
||||
In this example, the call to `boost::throw_with_location` is moved into
|
||||
a common helper function. Note how the "API" functions `f1` and `f2`
|
||||
take a source location argument that defaults to `BOOST_CURRENT_LOCATION`.
|
||||
This allows the source location attached to the exception to point at
|
||||
the location of the call to `f2`, rather than inside of `f2`.
|
||||
|
||||
Since functions such as `f2` are typically called from more than one place
|
||||
in the program, this is usually what we want, because it enables us to
|
||||
identify the throwing call, rather than merely to know that it was `f2`
|
||||
that threw.
|
||||
|
||||
[source,c++,linenums,highlight=38]
|
||||
----
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/verbose_terminate_handler.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
BOOST_NORETURN BOOST_NOINLINE
|
||||
void throw_invalid_argument( char const * msg,
|
||||
boost::source_location const & loc )
|
||||
{
|
||||
boost::throw_with_location( std::invalid_argument( msg ), loc );
|
||||
}
|
||||
|
||||
int f1( int x,
|
||||
boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
if( x < 0 )
|
||||
{
|
||||
throw_invalid_argument( "f1: x cannot be negative", loc );
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int f2( int x,
|
||||
boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
if( x < 0 )
|
||||
{
|
||||
throw_invalid_argument( "f2: x cannot be negative", loc );
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
|
||||
return f1( 3 ) + f2( -11 );
|
||||
}
|
||||
----
|
||||
|
||||
Sample output:
|
||||
|
||||
```none
|
||||
std::terminate called after throwing an exception:
|
||||
|
||||
type: boost::detail::with_throw_location<std::invalid_argument>
|
||||
what(): f2: x cannot be negative
|
||||
location: <source>:38:22 in function 'main'
|
||||
```
|
@ -3,4 +3,7 @@
|
||||
*:not(pre)>code { background: none; color: #600000; }
|
||||
:not(pre):not([class^=L])>code { background: none; color: #600000; }
|
||||
|
||||
pre.rouge .hll { background-color: #ffd; }
|
||||
pre.rouge .hll * { background-color: initial; }
|
||||
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2017, 2019 Peter Dimov
|
||||
Copyright 2017, 2019, 2022 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
@ -15,6 +15,7 @@ Peter Dimov, Emil Dotchevski
|
||||
:leveloffset: +1
|
||||
|
||||
include::description.adoc[]
|
||||
include::examples.adoc[]
|
||||
include::changes.adoc[]
|
||||
include::reference.adoc[]
|
||||
|
||||
@ -25,5 +26,5 @@ include::reference.adoc[]
|
||||
|
||||
This documentation is
|
||||
|
||||
* Copyright 2019 Peter Dimov
|
||||
* Copyright 2019, 2022 Peter Dimov
|
||||
* Distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
|
||||
|
@ -41,6 +41,16 @@ template<class E> BOOST_NORETURN void throw_exception( E const & e,
|
||||
|
||||
#define BOOST_THROW_EXCEPTION(x) \
|
||||
::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E && e,
|
||||
boost::source_location const & loc = BOOST_CURRENT_LOCATION );
|
||||
|
||||
template<class E> boost::source_location get_throw_location( E const & e );
|
||||
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## throw_exception
|
||||
@ -96,3 +106,32 @@ Effects: ::
|
||||
it, and containing the necessary support for `boost::exception_ptr`. The
|
||||
`boost::exception` base class is initialized to contain the source
|
||||
location `loc`.
|
||||
|
||||
## throw_with_location
|
||||
|
||||
```
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E && e,
|
||||
boost::source_location const & loc = BOOST_CURRENT_LOCATION );
|
||||
```
|
||||
|
||||
Requires: :: `std::decay<E>::type` must have `std::exception` as a public
|
||||
and unambiguous base class.
|
||||
|
||||
Effects: ::
|
||||
* When exceptions aren't available, `boost::throw_exception( e, loc );`
|
||||
* Otherwise, the function throws an object of a type derived from `E`,
|
||||
such that, if this object `x` is caught as `std::exception` or `E`,
|
||||
`boost::get_throw_location( x )` would return `loc`.
|
||||
|
||||
## get_throw_location
|
||||
|
||||
```
|
||||
template<class E> boost::source_location get_throw_location( E const & e );
|
||||
```
|
||||
|
||||
Requires: :: `E` must be polymorphic.
|
||||
Effects: ::
|
||||
* If `e` is a subobject of the object thrown by `boost::throw_with_location( x, loc )`, returns `loc`.
|
||||
* If `dynamic_cast<boost::exception const*>( e )` returns a nonzero value, returns the source location stored in that `boost::exception` subobject, if any.
|
||||
* Otherwise, returns a default constructed source location.
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
||||
#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
||||
|
||||
#include <boost/assert/source_location.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
|
||||
@ -107,6 +108,7 @@ boost
|
||||
typedef error_info<struct throw_function_,char const *> throw_function;
|
||||
typedef error_info<struct throw_file_,char const *> throw_file;
|
||||
typedef error_info<struct throw_line_,int> throw_line;
|
||||
typedef error_info<struct throw_column_,int> throw_column;
|
||||
|
||||
template <>
|
||||
class
|
||||
@ -150,6 +152,20 @@ boost
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class
|
||||
error_info<throw_column_,int>
|
||||
{
|
||||
public:
|
||||
typedef int value_type;
|
||||
value_type v_;
|
||||
explicit
|
||||
error_info( value_type v ):
|
||||
v_(v)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
exception;
|
||||
@ -189,6 +205,9 @@ boost
|
||||
template <>
|
||||
struct get_info<throw_line>;
|
||||
|
||||
template <>
|
||||
struct get_info<throw_column>;
|
||||
|
||||
template <class>
|
||||
struct set_info_rv;
|
||||
|
||||
@ -201,6 +220,9 @@ boost
|
||||
template <>
|
||||
struct set_info_rv<throw_line>;
|
||||
|
||||
template <>
|
||||
struct set_info_rv<throw_column>;
|
||||
|
||||
char const * get_diagnostic_information( exception const &, char const * );
|
||||
|
||||
void copy_boost_exception( exception *, exception const * );
|
||||
@ -216,6 +238,11 @@ boost
|
||||
|
||||
template <class E>
|
||||
E const & set_info( E const &, throw_line const & );
|
||||
|
||||
template <class E>
|
||||
E const & set_info( E const &, throw_column const & );
|
||||
|
||||
boost::source_location get_exception_throw_location( exception const & );
|
||||
}
|
||||
|
||||
class
|
||||
@ -233,7 +260,8 @@ boost
|
||||
exception():
|
||||
throw_function_(0),
|
||||
throw_file_(0),
|
||||
throw_line_(-1)
|
||||
throw_line_(-1),
|
||||
throw_column_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -244,7 +272,8 @@ boost
|
||||
data_(x.data_),
|
||||
throw_function_(x.throw_function_),
|
||||
throw_file_(x.throw_file_),
|
||||
throw_line_(x.throw_line_)
|
||||
throw_line_(x.throw_line_),
|
||||
throw_column_(x.throw_column_)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -269,27 +298,35 @@ boost
|
||||
template <class E>
|
||||
friend E const & exception_detail::set_info( E const &, throw_line const & );
|
||||
|
||||
template <class E>
|
||||
friend E const & exception_detail::set_info( E const &, throw_column const & );
|
||||
|
||||
template <class E,class Tag,class T>
|
||||
friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );
|
||||
|
||||
friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );
|
||||
|
||||
friend boost::source_location exception_detail::get_exception_throw_location( exception const & );
|
||||
|
||||
template <class>
|
||||
friend struct exception_detail::get_info;
|
||||
friend struct exception_detail::get_info<throw_function>;
|
||||
friend struct exception_detail::get_info<throw_file>;
|
||||
friend struct exception_detail::get_info<throw_line>;
|
||||
friend struct exception_detail::get_info<throw_column>;
|
||||
template <class>
|
||||
friend struct exception_detail::set_info_rv;
|
||||
friend struct exception_detail::set_info_rv<throw_function>;
|
||||
friend struct exception_detail::set_info_rv<throw_file>;
|
||||
friend struct exception_detail::set_info_rv<throw_line>;
|
||||
friend struct exception_detail::set_info_rv<throw_column>;
|
||||
friend void exception_detail::copy_boost_exception( exception *, exception const * );
|
||||
#endif
|
||||
mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
|
||||
mutable char const * throw_function_;
|
||||
mutable char const * throw_file_;
|
||||
mutable int throw_line_;
|
||||
mutable int throw_column_;
|
||||
};
|
||||
|
||||
inline
|
||||
@ -324,6 +361,42 @@ boost
|
||||
x.throw_line_=y.v_;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class E>
|
||||
E const &
|
||||
set_info( E const & x, throw_column const & y )
|
||||
{
|
||||
x.throw_column_=y.v_;
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template <>
|
||||
struct
|
||||
set_info_rv<throw_column>
|
||||
{
|
||||
template <class E>
|
||||
static
|
||||
E const &
|
||||
set( E const & x, throw_column && y )
|
||||
{
|
||||
x.throw_column_=y.v_;
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
inline boost::source_location get_exception_throw_location( exception const & x )
|
||||
{
|
||||
return boost::source_location(
|
||||
x.throw_file_? x.throw_file_: "",
|
||||
x.throw_line_ >= 0? x.throw_line_: 0,
|
||||
x.throw_function_? x.throw_function_: "",
|
||||
x.throw_column_ >= 0? x.throw_column_: 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -423,6 +496,7 @@ boost
|
||||
a->throw_file_ = b->throw_file_;
|
||||
a->throw_line_ = b->throw_line_;
|
||||
a->throw_function_ = b->throw_function_;
|
||||
a->throw_column_ = b->throw_column_;
|
||||
a->data_ = data;
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/throw_exception.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2018, 2019 Peter Dimov
|
||||
// Copyright (c) 2002, 2018-2022 Peter Dimov
|
||||
// Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
@ -18,14 +17,17 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// http://www.boost.org/libs/throw_exception
|
||||
//
|
||||
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/assert/source_location.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
|
||||
# define BOOST_EXCEPTION_DISABLE
|
||||
@ -104,6 +106,7 @@ public:
|
||||
set_info( *this, throw_file( loc.file_name() ) );
|
||||
set_info( *this, throw_line( loc.line() ) );
|
||||
set_info( *this, throw_function( loc.function_name() ) );
|
||||
set_info( *this, throw_column( loc.column() ) );
|
||||
}
|
||||
|
||||
virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
|
||||
@ -113,7 +116,7 @@ public:
|
||||
|
||||
boost::exception_detail::copy_boost_exception( p, this );
|
||||
|
||||
del.p_ = 0;
|
||||
del.p_ = BOOST_NULLPTR;
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -178,4 +181,98 @@ template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::sourc
|
||||
|
||||
#define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// throw_with_location
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE throw_location
|
||||
{
|
||||
boost::source_location location_;
|
||||
|
||||
explicit throw_location( boost::source_location const & loc ): location_( loc )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class E> class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location
|
||||
{
|
||||
public:
|
||||
|
||||
with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
throw_exception_assert_compatibility( e );
|
||||
throw detail::with_throw_location<typename std::decay<E>::type>( std::forward<E>( e ), loc );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
throw_exception_assert_compatibility( e );
|
||||
throw detail::with_throw_location<E>( e, loc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
boost::throw_exception( e, loc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// get_throw_location
|
||||
|
||||
template<class E> boost::source_location get_throw_location( E const & e )
|
||||
{
|
||||
#if defined(BOOST_NO_RTTI)
|
||||
|
||||
(void)e;
|
||||
return boost::source_location();
|
||||
|
||||
#else
|
||||
|
||||
if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
|
||||
{
|
||||
return pl->location_;
|
||||
}
|
||||
else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) )
|
||||
{
|
||||
return exception_detail::get_exception_throw_location( *px );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::source_location();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
|
||||
|
@ -31,9 +31,10 @@ run throw_exception_test5.cpp ;
|
||||
lib lib1_throw : lib1_throw.cpp : <define>LIB1_SOURCE=1 <link>shared:<define>LIB1_DYN_LINK=1 : : <link>shared:<define>LIB1_DYN_LINK=1 ;
|
||||
lib lib2_throw : lib2_throw.cpp : <define>LIB2_SOURCE=1 <link>shared:<define>LIB2_DYN_LINK=1 : : <link>shared:<define>LIB2_DYN_LINK=1 ;
|
||||
lib lib3_throw : lib3_throw.cpp : <define>LIB3_SOURCE=1 <link>shared:<define>LIB3_DYN_LINK=1 : : <link>shared:<define>LIB3_DYN_LINK=1 ;
|
||||
lib lib4_throw : lib4_throw.cpp : <define>LIB4_SOURCE=1 <link>shared:<define>LIB4_DYN_LINK=1 : : <link>shared:<define>LIB4_DYN_LINK=1 ;
|
||||
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw : : : <link>static : throw_from_library_static ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw : : : <link>shared : throw_from_library_shared ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw lib4_throw : : : <link>static : throw_from_library_static ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw lib4_throw : : : <link>shared : throw_from_library_shared ;
|
||||
|
||||
run throw_exception_nx_test.cpp : : : <exception-handling>off ;
|
||||
run throw_exception_nx_test2.cpp : : : <exception-handling>off ;
|
||||
@ -44,3 +45,12 @@ run make_exception_ptr_test2.cpp ;
|
||||
|
||||
run make_exception_ptr_nx_test.cpp : : : <exception-handling>off ;
|
||||
run make_exception_ptr_nx_test2.cpp : : : <exception-handling>off ;
|
||||
|
||||
run throw_with_location_test.cpp ;
|
||||
run throw_with_location_test2.cpp ;
|
||||
run throw_with_location_test3.cpp ;
|
||||
run throw_with_location_test4.cpp ;
|
||||
|
||||
run throw_with_location_nx_test.cpp : : : <exception-handling>off ;
|
||||
|
||||
run throw_with_location_test3.cpp : : : <rtti>off : throw_with_location_test3_nr ;
|
||||
|
14
test/lib4_throw.cpp
Normal file
14
test/lib4_throw.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2018, 2022 Peter Dimov
|
||||
//
|
||||
// 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 "lib4_throw.hpp"
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
void lib4::f()
|
||||
{
|
||||
boost::throw_with_location( lib4::exception() );
|
||||
}
|
35
test/lib4_throw.hpp
Normal file
35
test/lib4_throw.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef LIB4_THROW_HPP_INCLUDED
|
||||
#define LIB4_THROW_HPP_INCLUDED
|
||||
|
||||
// Copyright 2018, 2022 Peter Dimov
|
||||
//
|
||||
// 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>
|
||||
#include <exception>
|
||||
|
||||
#if defined(LIB4_DYN_LINK)
|
||||
# if defined(LIB4_SOURCE)
|
||||
# define LIB4_DECL BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define LIB4_DECL BOOST_SYMBOL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define LIB4_DECL
|
||||
#endif
|
||||
|
||||
namespace lib4
|
||||
{
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
LIB4_DECL void f();
|
||||
|
||||
} // namespace lib4
|
||||
|
||||
#endif // #ifndef LIB4_THROW_HPP_INCLUDED
|
@ -8,6 +8,7 @@
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cstring>
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
@ -21,6 +22,12 @@ class my_exception3: public std::exception, public virtual boost::exception
|
||||
{
|
||||
};
|
||||
|
||||
char const* translate_function( char const * fn, char const * cfn )
|
||||
{
|
||||
// translate "" and "main" to BOOST_CURRENT_FUNCTION
|
||||
return fn[0] == 0 || std::strcmp( fn, "main" ) == 0? cfn: fn;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
@ -40,14 +47,14 @@ int main()
|
||||
int const * line = boost::get_error_info<boost::throw_line>( x );
|
||||
|
||||
BOOST_TEST( line != 0 );
|
||||
BOOST_TEST_EQ( *line, 28 );
|
||||
BOOST_TEST_EQ( *line, 35 );
|
||||
}
|
||||
|
||||
{
|
||||
char const * const * function = boost::get_error_info<boost::throw_function>( x );
|
||||
|
||||
BOOST_TEST( function != 0 );
|
||||
BOOST_TEST_CSTR_EQ( *function, BOOST_CURRENT_FUNCTION );
|
||||
BOOST_TEST_CSTR_EQ( translate_function( *function, BOOST_CURRENT_FUNCTION ), BOOST_CURRENT_FUNCTION );
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,14 +75,14 @@ int main()
|
||||
int const * line = boost::get_error_info<boost::throw_line>( x );
|
||||
|
||||
BOOST_TEST( line != 0 );
|
||||
BOOST_TEST_EQ( *line, 56 );
|
||||
BOOST_TEST_EQ( *line, 63 );
|
||||
}
|
||||
|
||||
{
|
||||
char const * const * function = boost::get_error_info<boost::throw_function>( x );
|
||||
|
||||
BOOST_TEST( function != 0 );
|
||||
BOOST_TEST_CSTR_EQ( *function, BOOST_CURRENT_FUNCTION );
|
||||
BOOST_TEST_CSTR_EQ( translate_function( *function, BOOST_CURRENT_FUNCTION ), BOOST_CURRENT_FUNCTION );
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,14 +103,14 @@ int main()
|
||||
int const * line = boost::get_error_info<boost::throw_line>( x );
|
||||
|
||||
BOOST_TEST( line != 0 );
|
||||
BOOST_TEST_EQ( *line, 84 );
|
||||
BOOST_TEST_EQ( *line, 91 );
|
||||
}
|
||||
|
||||
{
|
||||
char const * const * function = boost::get_error_info<boost::throw_function>( x );
|
||||
|
||||
BOOST_TEST( function != 0 );
|
||||
BOOST_TEST_CSTR_EQ( *function, BOOST_CURRENT_FUNCTION );
|
||||
BOOST_TEST_CSTR_EQ( translate_function( *function, BOOST_CURRENT_FUNCTION ), BOOST_CURRENT_FUNCTION );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "lib1_throw.hpp"
|
||||
#include "lib2_throw.hpp"
|
||||
#include "lib3_throw.hpp"
|
||||
#include "lib4_throw.hpp"
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
@ -30,6 +31,7 @@ void test_catch_by_type()
|
||||
BOOST_TEST_THROWS( lib1::f(), lib1::exception );
|
||||
BOOST_TEST_THROWS( lib2::f(), lib2::exception );
|
||||
BOOST_TEST_THROWS( lib3::f(), lib3::exception );
|
||||
BOOST_TEST_THROWS( lib4::f(), lib4::exception );
|
||||
}
|
||||
|
||||
void test_catch_by_exception()
|
||||
@ -78,6 +80,25 @@ void test_throw_line()
|
||||
BOOST_TEST( line != 0 );
|
||||
BOOST_TEST_EQ( *line, 13 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "lib3::f failed to throw boost::exception" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
lib4::f();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_NE( loc.line(), 0u );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "lib4::f failed to throw std::exception" );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
30
test/throw_with_location_nx_test.cpp
Normal file
30
test/throw_with_location_nx_test.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2019, 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
# pragma warning(disable: 4577) // noexcept used without /EHsc
|
||||
# pragma warning(disable: 4530) // C++ exception handler used
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
class my_exception: public std::exception {};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::throw_with_location( my_exception() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
void throw_exception( std::exception const &, boost::source_location const & )
|
||||
{
|
||||
std::exit( 0 );
|
||||
}
|
||||
|
||||
} // namespace boost
|
22
test/throw_with_location_test.cpp
Normal file
22
test/throw_with_location_test.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_THROWS( boost::throw_with_location( my_exception() ), my_exception );
|
||||
BOOST_TEST_THROWS( boost::throw_with_location( my_exception() ), std::exception );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
64
test/throw_with_location_test2.cpp
Normal file
64
test/throw_with_location_test2.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::throw_with_location( my_exception() );
|
||||
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw" );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
// When not supplied explicitly, the source location is best effort.
|
||||
// It should be the location of the throw_with_location call on
|
||||
// recent compilers, but that's not guaranteed for every compiler.
|
||||
// So we can't be more specific in testing it.
|
||||
|
||||
BOOST_TEST_CSTR_NE( loc.file_name(), "" );
|
||||
BOOST_TEST_NE( loc.line(), 0u );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw std::exception" );
|
||||
}
|
||||
|
||||
boost::source_location location = BOOST_CURRENT_LOCATION;
|
||||
|
||||
try
|
||||
{
|
||||
boost::throw_with_location( my_exception(), location );
|
||||
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw" );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_CSTR_EQ( loc.file_name(), location.file_name() );
|
||||
BOOST_TEST_CSTR_EQ( loc.function_name(), location.function_name() );
|
||||
BOOST_TEST_EQ( loc.line(), location.line() );
|
||||
BOOST_TEST_EQ( loc.column(), location.column() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw std::exception" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
33
test/throw_with_location_test3.cpp
Normal file
33
test/throw_with_location_test3.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw my_exception();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_CSTR_EQ( loc.file_name(), "" );
|
||||
BOOST_TEST_CSTR_EQ( loc.function_name(), "" );
|
||||
BOOST_TEST_EQ( loc.line(), 0u );
|
||||
BOOST_TEST_EQ( loc.column(), 0u );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
41
test/throw_with_location_test4.cpp
Normal file
41
test/throw_with_location_test4.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::source_location location = BOOST_CURRENT_LOCATION;
|
||||
|
||||
try
|
||||
{
|
||||
boost::throw_exception( my_exception(), location );
|
||||
|
||||
BOOST_ERROR( "boost::throw_exception failed to throw" );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_CSTR_EQ( loc.file_name(), location.file_name() );
|
||||
BOOST_TEST_CSTR_EQ( loc.function_name(), location.function_name() );
|
||||
BOOST_TEST_EQ( loc.line(), location.line() );
|
||||
BOOST_TEST_EQ( loc.column(), location.column() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "boost::throw_exception failed to throw std::exception" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user