1 // 2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // Official repository: https://github.com/boostorg/beast 8 // 9 10 // Test that header file is self-contained. 11 #include <boost/beast/core/saved_handler.hpp> 12 13 #include <boost/beast/_experimental/unit_test/suite.hpp> 14 #include <stdexcept> 15 16 namespace boost { 17 namespace beast { 18 19 //------------------------------------------------------------------------------ 20 21 class saved_handler_test : public unit_test::suite 22 { 23 public: 24 class handler 25 { 26 bool failed_ = true; 27 bool throw_on_move_ = false; 28 29 public: 30 handler() = default; 31 handler(handler const&) = delete; 32 handler& operator=(handler&&) = delete; 33 handler& operator=(handler const&) = delete; 34 ~handler()35 ~handler() 36 { 37 BEAST_EXPECT(! failed_); 38 } 39 handler(handler && other)40 handler(handler&& other) 41 : failed_(boost::exchange( 42 other.failed_, false)) 43 { 44 if(throw_on_move_) 45 throw std::bad_alloc{}; 46 } 47 48 void operator ()()49 operator()() 50 { 51 failed_ = false; 52 } 53 }; 54 55 class unhandler 56 { 57 bool invoked_ = false; 58 59 public: 60 unhandler() = default; 61 unhandler(unhandler const&) = delete; 62 unhandler& operator=(unhandler&&) = delete; 63 unhandler& operator=(unhandler const&) = delete; 64 ~unhandler()65 ~unhandler() 66 { 67 BEAST_EXPECT(! invoked_); 68 } 69 unhandler(unhandler && other)70 unhandler(unhandler&& other) 71 : invoked_(boost::exchange( 72 other.invoked_, false)) 73 { 74 } 75 76 void operator ()()77 operator()() 78 { 79 invoked_ = true; 80 } 81 }; 82 83 struct throwing_handler 84 { 85 throwing_handler() = default; 86 throwing_handlerboost::beast::saved_handler_test::throwing_handler87 throwing_handler(throwing_handler&&) 88 { 89 BOOST_THROW_EXCEPTION(std::exception{}); 90 } 91 92 void operator ()boost::beast::saved_handler_test::throwing_handler93 operator()() 94 { 95 } 96 }; 97 98 void testSavedHandler()99 testSavedHandler() 100 { 101 { 102 saved_handler sh; 103 BEAST_EXPECT(! sh.has_value()); 104 105 sh.emplace(handler{}); 106 BEAST_EXPECT(sh.has_value()); 107 sh.invoke(); 108 BEAST_EXPECT(! sh.has_value()); 109 110 sh.emplace(handler{}, std::allocator<char>{}); 111 BEAST_EXPECT(sh.has_value()); 112 sh.invoke(); 113 BEAST_EXPECT(! sh.has_value()); 114 115 sh.emplace(unhandler{}); 116 BEAST_EXPECT(sh.has_value()); 117 } 118 119 { 120 saved_handler sh; 121 try 122 { 123 sh.emplace(throwing_handler{}); 124 fail(); 125 } 126 catch(std::exception const&) 127 { 128 pass(); 129 } 130 BEAST_EXPECT(! sh.has_value()); 131 } 132 } 133 134 void run()135 run() override 136 { 137 testSavedHandler(); 138 } 139 }; 140 141 BEAST_DEFINE_TESTSUITE(beast,core,saved_handler); 142 143 } // beast 144 } // boost 145