1 // Copyright (c) 2018 Andrey Semashev
2 //
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 // The test verifies that Boost.Optional copy constructors do not attempt to invoke
8 // the element type initializing constructors from templated arguments
9
10 #include <boost/optional/optional.hpp>
11 #include <boost/core/enable_if.hpp>
12
13 struct no_type
14 {
15 char data;
16 };
17
18 struct yes_type
19 {
20 char data[2];
21 };
22
23 template< unsigned int Size >
24 struct size_tag {};
25
26 template< typename T, typename U >
27 struct is_constructible
28 {
29 static U& get();
30
31 template< typename T1 >
32 static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(get())) >*);
33 template< typename T1 >
34 static no_type check_helper(...);
35
36 static const bool value = sizeof(check_helper< T >(0)) == sizeof(yes_type);
37 };
38
39 template< typename T >
40 class wrapper
41 {
42 public:
wrapper()43 wrapper() {}
wrapper(wrapper const &)44 wrapper(wrapper const&) {}
45 template< typename U >
wrapper(U const &,typename boost::enable_if_c<is_constructible<T,U>::value,int>::type=0)46 wrapper(U const&, typename boost::enable_if_c< is_constructible< T, U >::value, int >::type = 0) {}
47 };
48
foo()49 inline boost::optional< wrapper< int > > foo()
50 {
51 return boost::optional< wrapper< int > >();
52 }
53
main()54 int main()
55 {
56 // Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
57 boost::optional< wrapper< int > > res = foo();
58 return 0;
59 }
60