1
0
forked from boostorg/core

Compare commits

...

18 Commits

Author SHA1 Message Date
Andrey Semashev
622476533c Added a release notes entry for the empty_value fix. 2024-07-27 10:35:28 +03:00
Andrey Semashev
76d0f22d3b Added 1.86.0 release notes. 2024-07-24 03:02:00 +03:00
Glen Fernandes
9e9e6e3898 Rename base type again 2024-07-16 23:53:47 -04:00
Glen Fernandes
242b14bb69 Rename base typedef 2024-07-14 07:14:38 -04:00
Glen Fernandes
76061d91d4 Move compile test to separate source file 2024-07-14 07:04:23 -04:00
Peter Dimov
bda05a7812 Update .drone.jsonnet 2024-07-13 15:41:26 +03:00
Peter Dimov
d66b8c1c13 Update ci.yml 2024-07-13 13:32:29 +03:00
Andrey Semashev
bd29e0dd15 Merge pull request #177 from ashtum/rename-base-typedef
Rename typedef `base` to `core_ev_base`
2024-07-13 13:21:00 +03:00
Mohammad Nejati
72761e34e0 Rename typedef base to core_ev_base
Using typedef `base` poses a high risk of name conflict, given that
`empty_value` is inherited in user types.
2024-07-13 09:14:58 +00:00
Glen Fernandes
83a3a51bee Merge pull request #175 from k3DW/feature/empty-value-inherit-public
Fix `empty_value` MSVC bug
2024-07-12 08:53:53 -04:00
Braden Ganetsky
acbeaae181 Add link to Visual Studio bug report 2024-07-11 17:02:24 -05:00
Braden Ganetsky
d01b4e94cc Write test for empty_value private inheritance 2024-07-11 17:02:23 -05:00
Braden Ganetsky
e22bd49fa7 Fix MSVC issue with deriving from empty_value 2024-07-11 17:02:21 -05:00
Braden Ganetsky
c056f3dfc9 Write failing test in MSVC for deriving from empty_value 2024-06-23 22:50:52 -05:00
Peter Dimov
3f36d507f2 Disable the tn_holder<wchar_t> specialization when BOOST_NO_INTRINSIC_WCHAR_T. Refs #173. 2024-05-28 19:32:36 +03:00
Andrey Semashev
a77338b1cd Use macos-14 image instead of macos-11 as the latter is being removed. 2024-05-21 01:06:02 +03:00
Peter Dimov
965508d9e1 Fix type_name for abstract classes. Fixes #172. 2024-04-24 21:46:32 +03:00
Glen Fernandes
d03e58b77e Correct parameter type in documentation 2024-04-18 13:16:12 -04:00
11 changed files with 221 additions and 40 deletions

View File

@@ -200,31 +200,38 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN",
"Linux 23.04 GCC 13 32/64",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + asan,
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' },
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-13-multilib",
"Linux 24.04 GCC 14 32 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-13-multilib",
"Linux 24.04 GCC 14 64 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-13-multilib",
"Linux 24.04 GCC 14 32 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 64 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
@@ -354,17 +361,24 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.10 Clang 17 UBSAN",
"Linux 23.10 Clang 17",
"cppalliance/droneubuntu2310:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' },
"clang-17",
),
linux_pipeline(
"Linux 23.10 Clang 17 ASAN",
"cppalliance/droneubuntu2310:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' } + asan,
"clang-17",
"Linux 24.04 Clang 18 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 18 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' } + asan,
"clang-18",
),
macos_pipeline(

View File

@@ -128,6 +128,13 @@ jobs:
container: ubuntu:23.04
install:
- g++-13-multilib
- toolset: gcc-14
cxxstd: "03,11,14,17,20,23"
address-model: 32,64
os: ubuntu-latest
container: ubuntu:24.04
install:
- g++-14-multilib
- name: UBSAN
toolset: gcc-12
cxxstd: "03,11,14,17,20,23"
@@ -286,15 +293,23 @@ jobs:
- toolset: clang
compiler: clang++-17
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
os: ubuntu-latest
container: ubuntu:23.10
install:
- clang-17
- libc++-17-dev
- libc++abi-17-dev
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-18
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install:
- clang-18
- libc++-18-dev
- libc++abi-18-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
@@ -310,15 +325,15 @@ jobs:
- libc++-15-dev
- libc++abi-15-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-12
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-14
timeout-minutes: 45
runs-on: ${{matrix.os}}
@@ -611,9 +626,9 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -678,9 +693,9 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -755,9 +770,9 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
timeout-minutes: 20

View File

@@ -7,12 +7,24 @@
[section Revision History]
[section Changes in 1.86.0]
* Added a [link core.pointer_in_range `boost/core/pointer_in_range.hpp`] header with a `pointer_in_range`
function template to check if a pointer is within a given range.
* Fixed `type_name` for abstract classes. ([github_issue 172])
* Fixed `boost/core/type_name.hpp` compilation error with MSVC with disabled native `wchar_t` type.
([github_issue 173])
* Added a workaround for an MSVC [@https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025 bug]
causing `empty_value` compilation errors when it is used with a nested class. ([github_pr 175])
[endsect]
[section Changes in 1.85.0]
* Added a new [link core.functor `boost/core/functor.hpp`] header with a `functor` class template
for wrapping a raw function into a function object class.
* Changed [link core.null_deleter `null_deleter`], [link core.fclose_deleter `fclose_deleter`]
and [link.checked_delete checked deleter] definitions so that they don't bring namespace `boost`
and [link core.checked_delete checked deleter] definitions so that they don't bring namespace `boost`
into argument-dependent lookup in cases like this:
```
std::unique_ptr< std::FILE, boost::fclose_deleter > p1, p2;

View File

@@ -20,6 +20,9 @@ or copy at http://boost.org/LICENSE_1_0.txt)
]
]
[template github_issue[key]'''<ulink url="https://github.com/boostorg/core/issues/'''[key]'''">#'''[key]'''</ulink>''']
[template github_pr[key]'''<ulink url="https://github.com/boostorg/core/pull/'''[key]'''">PR#'''[key]'''</ulink>''']
[template simplesect[title]
[block '''<simplesect><title>'''[title]'''</title>''']]

View File

@@ -56,7 +56,7 @@ constexpr bool pointer_in_range(const T* ptr, const T* begin, const T* end);
[variablelist
[[`template<class T> constexpr bool pointer_in_range(const T* ptr,
const T* begin, T* end);`]
const T* begin, const T* end);`]
[[variablelist
[[Requires][`[begin,end)` is a valid range.]]
[[Returns][`true` if `ptr` is in range `[begin,end)`, otherwise `false`.]]]]]]

View File

@@ -95,9 +95,57 @@ private:
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#if defined(BOOST_MSVC)
/*
This is a workaround to an MSVC bug when T is a nested class:
https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025
*/
namespace detail {
template<class T>
class empty_value_base
: public T {
public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value_base() = default;
#else
BOOST_CONSTEXPR empty_value_base() { }
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
BOOST_CONSTEXPR empty_value_base(U&& value, Args&&... args)
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
BOOST_CONSTEXPR empty_value_base(U&& value)
: T(std::forward<U>(value)) { }
#endif
#else
template<class U>
BOOST_CONSTEXPR empty_value_base(const U& value)
: T(value) { }
template<class U>
BOOST_CONSTEXPR empty_value_base(U& value)
: T(value) { }
#endif
};
} /* detail */
#endif
template<class T, unsigned N>
class empty_value<T, N, true>
#if defined(BOOST_MSVC)
: detail::empty_value_base<T> {
typedef detail::empty_value_base<T> empty_base_;
#else
: T {
typedef T empty_base_;
#endif
public:
typedef T type;
@@ -108,26 +156,26 @@ public:
#endif
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
: T() { }
: empty_base_() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
: empty_base_(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
: T(std::forward<U>(value)) { }
: empty_base_(std::forward<U>(value)) { }
#endif
#else
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
: T(value) { }
: empty_base_(value) { }
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
: T(value) { }
: empty_base_(value) { }
#endif
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {

View File

@@ -103,7 +103,8 @@ inline std::string fix_typeid_name( char const* n )
}
// class types can be incomplete
template<class T> std::string typeid_name_impl( int T::* )
// but also abstract (T[1] doesn't form)
template<class T> std::string typeid_name_impl( int T::*, T(*)[1] )
{
std::string r = fix_typeid_name( typeid(T[1]).name() );
return r.substr( 0, r.size() - 4 ); // remove ' [1]' suffix
@@ -116,7 +117,7 @@ template<class T> std::string typeid_name_impl( ... )
template<class T> std::string typeid_name()
{
return typeid_name_impl<T>( 0 );
return typeid_name_impl<T>( 0, 0 );
}
// template names
@@ -345,6 +346,8 @@ template<> struct tn_holder<boost::uint128_type>
#endif
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template<> struct tn_holder<wchar_t>
{
static std::string type_name( std::string const& suffix )
@@ -353,6 +356,8 @@ template<> struct tn_holder<wchar_t>
}
};
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template<> struct tn_holder<char16_t>

View File

@@ -226,6 +226,8 @@ run empty_value_test.cpp ;
run empty_value_size_test.cpp ;
run empty_value_final_test.cpp ;
run empty_value_constexpr_test.cpp ;
compile empty_value_nested_test.cpp ;
compile-fail empty_value_compile_fail_casting.cpp ;
run quick_exit_test.cpp ;
run-fail quick_exit_fail.cpp ;

View File

@@ -0,0 +1,20 @@
// Copyright 2024 Braden Ganetsky
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/empty_value.hpp>
struct empty {};
// This test ensures private inheritance of `boost::empty_value<T>` for empty `T`.
// With public inheritance, `boost::empty_value<empty>*` could cast to `empty*`.
void test_empty_not_convertible_to_base()
{
const boost::empty_value<empty> x(boost::empty_init);
const empty* x2 = static_cast<const empty*>(&x);
(void)x2;
}
int main()
{
}

View File

@@ -0,0 +1,45 @@
/*
Copyright 2024 Braden Ganetsky
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/core/empty_value.hpp>
/*
Tests workaround for MSVC bug:
https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025
*/
template<class T>
struct derived
: boost::empty_value<T> {
typedef typename boost::empty_value<T>::type type;
derived(boost::empty_init_t e)
: boost::empty_value<T>(e) { }
};
struct outer {
struct inner_empty { };
struct inner_non_empty {
inner_non_empty()
: value() { }
int value;
};
};
void test()
{
const boost::empty_value<outer> x1(boost::empty_init);
(void)x1;
const boost::empty_value<outer::inner_empty> x2(boost::empty_init);
(void)x2;
const boost::empty_value<outer::inner_non_empty> x3(boost::empty_init);
(void)x3;
const derived<outer> x4(boost::empty_init);
(void)x4;
const derived<outer::inner_empty> x5(boost::empty_init);
(void)x5;
const derived<outer::inner_non_empty> x6(boost::empty_init);
(void)x6;
}

View File

@@ -55,6 +55,13 @@ template<class T1, class T2> struct X
template<class T1, class T2> struct Y;
class W
{
public:
virtual void f() = 0;
};
enum E1
{
e1
@@ -122,6 +129,7 @@ int main()
TEST(A);
TEST(B);
TEST(C);
TEST(W);
TEST(E1);
@@ -143,6 +151,9 @@ int main()
TEST(C&);
TEST(C const&);
TEST(W const);
TEST(W&);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
TEST(B&&);
@@ -156,6 +167,8 @@ int main()
TEST(C*);
TEST(C const* volatile*);
TEST(W volatile*);
TEST(void*);
TEST(void const* volatile*);
@@ -307,6 +320,8 @@ int main()
TEST(std::pair<C, C>);
TEST(std::pair<W, W>);
TEST(std::pair<void, void>);
TEST(std::pair<std::pair<void, void>, void>);
@@ -336,9 +351,11 @@ int main()
TEST(X<A const&, B&> volatile&);
TEST(X<C, C>);
TEST(X<W, W>);
TEST(Y<A, B>);
TEST(Y<C, C>);
TEST(Y<W, W>);
TEST(X<std::pair<void, void>, void>);