optional_test_constructible_from_other.cpp 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  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. // The test verifies that Boost.Optional copy constructors do not attempt to invoke
  7. // the element type initializing constructors from templated arguments
  8. #include <boost/optional/optional.hpp>
  9. #include <boost/core/enable_if.hpp>
  10. struct no_type
  11. {
  12. char data;
  13. };
  14. struct yes_type
  15. {
  16. char data[2];
  17. };
  18. template< unsigned int Size >
  19. struct size_tag {};
  20. template< typename T, typename U >
  21. struct is_constructible
  22. {
  23. template< typename T1, typename U1 >
  24. static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(U1())) >*);
  25. template< typename T1, typename U1 >
  26. static no_type check_helper(...);
  27. static const bool value = sizeof(check_helper< T, U >(0)) == sizeof(yes_type);
  28. };
  29. template< typename T >
  30. class wrapper
  31. {
  32. public:
  33. wrapper() {}
  34. wrapper(wrapper const&) {}
  35. template< typename U >
  36. wrapper(U const&, typename boost::enable_if_c< is_constructible< T, U >::value, int >::type = 0) {}
  37. };
  38. inline boost::optional< wrapper< int > > foo()
  39. {
  40. return boost::optional< wrapper< int > >();
  41. }
  42. int main()
  43. {
  44. // Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
  45. boost::optional< wrapper< int > > res = foo();
  46. return 0;
  47. }