• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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