// Copyright (C) 2026 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/lib/optional for documentation. // // You are welcome to contact the author at: // akrzemi1@gmail.com #include "boost/optional/optional.hpp" #include "boost/core/lightweight_test.hpp" #include using boost::optional; using boost::none; struct MyBool { bool b; MyBool (bool b) : b(b) {} operator bool() const { return b; }; }; struct MyExplicitBool { bool b; MyExplicitBool (bool b) : b(b) {} operator bool() const { return b; }; }; struct Any { template Any(T&&...) {} }; struct JustCopyMoveCtor { JustCopyMoveCtor(JustCopyMoveCtor&&) = default; JustCopyMoveCtor(JustCopyMoveCtor const&) = default; JustCopyMoveCtor& operator=(JustCopyMoveCtor&&) = delete; JustCopyMoveCtor& operator=(JustCopyMoveCtor const&) = delete; JustCopyMoveCtor() = delete; }; struct JustDefault { JustDefault() = default; JustDefault(JustDefault&&) = delete; }; template optional empty_optional() { return optional(); // this is to avoid "the most vexing parse" } template void direct_test_ctor_optional_T_from_empty_optional_T() { optional om; const optional oc; BOOST_TEST(!om); BOOST_TEST(!oc); { optional ox = om; BOOST_TEST(!ox); optional oy = oc; BOOST_TEST(!oy); optional oz = empty_optional(); BOOST_TEST(!oz); } { optional ox = {om}; BOOST_TEST(!ox); optional oy = {oc}; BOOST_TEST(!oy); optional oz = {empty_optional()}; BOOST_TEST(!oz); } { optional ox{om}; BOOST_TEST(!ox); optional oy{oc}; BOOST_TEST(!oy); optional oz{empty_optional()}; BOOST_TEST(!oz); } { optional ox(om); BOOST_TEST(!ox); optional oy(oc); BOOST_TEST(!oy); optional oz(empty_optional()); BOOST_TEST(!oz); } } template void test_ctor_optional_T_from_empty_optional_T() { direct_test_ctor_optional_T_from_empty_optional_T(); direct_test_ctor_optional_T_from_empty_optional_T(); direct_test_ctor_optional_T_from_empty_optional_T, optional>(); direct_test_ctor_optional_T_from_empty_optional_T, optional>(); direct_test_ctor_optional_T_from_empty_optional_T, const optional>(); } template void direct_test_ctor_optional_T_from_optional_U(U val) { optional om; const optional oc; BOOST_TEST(!om); BOOST_TEST(!oc); { optional ox{om}; BOOST_TEST(!ox); optional oy{oc}; BOOST_TEST(!oy); optional oz{empty_optional()}; BOOST_TEST(!oz); } { optional ox(om); BOOST_TEST(!ox); optional oy(oc); BOOST_TEST(!oy); optional oz(empty_optional()); BOOST_TEST(!oz); } { optional om {val}; const optional oc {val}; { optional ox{om}; BOOST_TEST(ox); optional oy{oc}; BOOST_TEST(oy); optional oz{boost::make_optional(val)}; BOOST_TEST(oz); } { optional ox(om); BOOST_TEST(ox); optional oy(oc); BOOST_TEST(oy); optional oz(boost::make_optional(val)); BOOST_TEST(oz); } } } template void test_ctor_optional_T_from_optional_U(U val) { direct_test_ctor_optional_T_from_optional_U(val); } template void direct_test_ctor_optional_T_from_valued_optional_T(T val) { optional om(val); const optional oc(val); BOOST_TEST(om); BOOST_TEST(oc); { optional ox = om; BOOST_TEST(ox); optional oy = oc; BOOST_TEST(oy); optional oz = optional(val); BOOST_TEST(oz); } { optional ox = {om}; BOOST_TEST(ox); optional oy = {oc}; BOOST_TEST(oy); optional oz = {optional(val)}; BOOST_TEST(oz); } } template void test_ctor_optional_T_from_valued_optional_T(T val) { direct_test_ctor_optional_T_from_valued_optional_T(val); direct_test_ctor_optional_T_from_valued_optional_T>(val); direct_test_ctor_optional_T_from_valued_optional_T(val); direct_test_ctor_optional_T_from_optional_U(val); direct_test_ctor_optional_T_from_optional_U, optional>(val); } template void direct_test_inplace_tag_constructor() { { optional ox (boost::in_place_init); BOOST_TEST(ox); } { optional ox {boost::in_place_init}; BOOST_TEST(ox); } } template void test_inplace_tag_constructor() { direct_test_inplace_tag_constructor(); direct_test_inplace_tag_constructor>(); } int main() { test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_ctor_optional_T_from_empty_optional_T(); test_inplace_tag_constructor(); test_inplace_tag_constructor(); test_inplace_tag_constructor(); test_ctor_optional_T_from_optional_U(1); test_ctor_optional_T_from_optional_U(1); test_ctor_optional_T_from_optional_U(MyBool{true}); test_ctor_optional_T_from_optional_U(MyBool{false}); test_ctor_optional_T_from_optional_U(true); test_ctor_optional_T_from_optional_U(false); test_ctor_optional_T_from_optional_U(MyExplicitBool{true}); test_ctor_optional_T_from_optional_U(MyExplicitBool{false}); test_ctor_optional_T_from_optional_U(true); test_ctor_optional_T_from_optional_U(false); test_ctor_optional_T_from_optional_U(true); test_ctor_optional_T_from_optional_U(Any{}); test_ctor_optional_T_from_valued_optional_T(1); optional ob; optional oa; oa = ob; BOOST_TEST(!oa); return boost::report_errors(); }