diff --git a/doc/changes.adoc b/doc/changes.adoc index 618e508..782c37b 100644 --- a/doc/changes.adoc +++ b/doc/changes.adoc @@ -15,6 +15,9 @@ http://www.boost.org/LICENSE_1_0.txt * `source_location().file_name()` and `source_location().function_name()` now return `""` instead of `"(unknown)"`. * Added a `source_location` constructor from `std::source_location`. +* Changed `BOOST_CURRENT_LOCATION` to more closely match the behavior of + `std::source_location::current()`, such as being usable at top level or + as a default function argument. ## Changes in 1.78.0 diff --git a/doc/index.adoc b/doc/index.adoc index 7fed886..9873bdb 100644 --- a/doc/index.adoc +++ b/doc/index.adoc @@ -32,7 +32,7 @@ include::changes.adoc[] This documentation is -* Copyright 2002, 2007, 2014, 2017, 2019-2021 Peter Dimov +* Copyright 2002, 2007, 2014, 2017, 2019-2022 Peter Dimov * Copyright 2011 Beman Dawes * Copyright 2015 Ion GaztaƱaga * Distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. diff --git a/doc/source_location.adoc b/doc/source_location.adoc index bed61cd..8d0adc9 100644 --- a/doc/source_location.adoc +++ b/doc/source_location.adoc @@ -1,5 +1,5 @@ //// -Copyright 2019, 2021 Peter Dimov +Copyright 2019, 2021, 2022 Peter Dimov Distributed under the Boost Software License, Version 1.0. http://www.boost.org/LICENSE_1_0.txt //// @@ -18,7 +18,74 @@ and column information. It's similar to `std::source_location` from {cpp}20, but only requires {cpp}03. The macro `BOOST_CURRENT_LOCATION` creates a `source_location` object -containing information about the current source location. +containing information about the current source location. It can be used +roughly in the same way `std::source_location::current()` can be used, +such as in the declaration of a function default argument: + +``` +#include +#include + +void f( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) +{ + std::cout << "f() called from: " << loc << std::endl; +} + +int main() +{ + f(); +} +``` + +The output of this example varies by compiler and C++ standard level, but +it's generally one of + +```none +f() called from: example.cpp:11:6 in function 'int main()' +``` +```none +f() called from: example.cpp:11:5 in function 'main' +``` +```none +f() called from: example.cpp:11 in function 'main' +``` +```none +f() called from: example.cpp:11 in function 'main' +``` +```none +f() called from: example.cpp:4 +``` + +This is useful if, for example, you want to declare a function that throws +an exception, such that the source location of the caller is attached to +the thrown exception: + +``` +BOOST_NORETURN BOOST_NOINLINE void throw_invalid_argument( + char const* message, + boost::source_location const& loc = BOOST_CURRENT_LOCATION ) +{ + boost::throw_exception( std::invalid_argument( message ), loc ); +} +``` + +Now you could use this helper function in, say, the implementation of +`at` to signal an index that is out of range: + +``` +T& my_class::at( size_t i ) +{ + if( i >= size() ) throw_invalid_argument( "index out of range" ); + return data()[ i ]; +} +``` + +This would attach the source location of the line in `at` that calls +`throw_invalid_argument` to the thrown exception. + +Note that if instead you use `BOOST_THROW_EXCEPTION` in +`throw_invalid_argument`, the location will be that of +`throw_invalid_argument` and not of its caller. ## Synopsis @@ -47,8 +114,7 @@ template } // namespace boost -#define BOOST_CURRENT_LOCATION \ - ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) +#define BOOST_CURRENT_LOCATION /* see below */ ``` ## source_location @@ -100,19 +166,20 @@ Returns: :: ## BOOST_CURRENT_LOCATION -When `BOOST_DISABLE_CURRENT_LOCATION` is not defined, the definition of +When `BOOST_DISABLE_CURRENT_LOCATION` is defined, the definition of `BOOST_CURRENT_LOCATION` is: -``` -#define BOOST_CURRENT_LOCATION \ - ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) -``` - -Otherwise, `BOOST_CURRENT_LOCATION` is defined as: - ``` #define BOOST_CURRENT_LOCATION ::boost::source_location() ``` This allows producing executables that contain no identifying information, for security reasons. + +Otherwise, `BOOST_CURRENT_LOCATION` is defined as the approximate equivalent +of + +``` +#define BOOST_CURRENT_LOCATION \ + ::boost::source_location(::std::source_location::current()) +```