src/boost_ci.cpp

88.9% Lines (16/0/18) 75.0% List of functions (3/0/4)
boost_ci.cpp
f(x) Functions (4)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2022-2026 Alexander Grund
3 //
4 // Use, modification and distribution is subject to the Boost Software License,
5 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 #define BOOST_BOOST_CI_SOURCE
9
10 #include <boost/boost-ci/boost_ci.hpp>
11 // Just some dependency on another Boost library
12 #include <boost/atomic/atomic.hpp>
13
14 #if !(defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_AUTO_DECLARATIONS))
15 #define BOOST_BOOST_CI_TEST_BIND_ISSUE
16 #include <functional>
17 #include <map>
18 #endif
19 #include <utility>
20
21 // Some simple struct big enough so that the atomic is forced to use a lock
22 // forcing it to call into the library
23 struct X
24 {
25 double x, y, z;
26 5x explicit X(int value = 0): x(value), y(value), z(value) {}
27 };
28
29 namespace boost
30 {
31 namespace boost_ci
32 {
33 void reproducer();
34 // Some function to test
35 3x int get_answer(const int isMsvc)
36 {
37 3x reproducer();
38 3x boost::atomic<X> answer;
39 // Specifically crafted condition to check for coverage from MSVC and non MSVC builds
40 3x if(isMsvc == 1)
41 answer = X(21);
42 3x else if(isMsvc == 0)
43 4x answer = X(42);
44 else
45 1x throw example_error();
46 #ifdef BOOST_NO_CXX11_SMART_PTR
47 return answer.load().x;
48 #else
49 // Just use some stdlib feature combined with a Boost.Config feature as demonstration
50 4x auto ptr = std::unique_ptr<int>(new int(answer.load().x));
51 4x return *ptr;
52 #endif
53 2x }
54
55 #ifdef BOOST_BOOST_CI_TEST_BIND_ISSUE
56 // Reproducer for a bug observed in Clang 16 with libstdc++
57 void f(const std::pair<int, float>&) {}
58
59 3x void reproducer() {
60 6x std::map<int, float> m{{0, 0.f}, {1, 1.f}};
61
62 // Bind a map element (value_type is pair<const int, float>).
63 3x auto bound = std::bind(f, *m.begin());
64
65 // The libstdc++ failure happens during instantiation of the defaulted move constructor of std::_Bind,
66 // when it checks whether std::pair can be constructed from the internal tuple-like storage.
67 3x auto bound2 = std::move(bound);
68 (void)bound2;
69 3x }
70 #else
71 void reproducer() {}
72 #endif
73 }
74 }
75