// Copyright 2014 The Emscripten Authors. All rights reserved. // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. #include #include #include #include namespace { struct TestEnum { enum type { Zero, One }; }; // An input operator a-la-boost date_time. This input operator will catch // anything and rethrow if the exception mask for the input stream is set to // throw on failure. std::istream& operator>>(std::istream& in, TestEnum::type& value) { try { std::string raw; if (not (in >> raw)) { return in; } if (raw == "Zero") { value = TestEnum::Zero; return in; } if (raw == "One") { value = TestEnum::One; return in; } // The boost input operator uses it's own facet for input which can // throw, so we simulate something failing by just throwing an exception // directly. throw std::exception(); } catch (...) { const std::ios_base::iostate exception_mask = in.exceptions(); if (std::ios_base::failbit & exception_mask) { try { in.setstate(std::ios_base::failbit); } catch(std::ios_base::failure&) {} throw; // rethrow original exception } else { in.setstate(std::ios_base::failbit); } } return in; } } int main() { try { // Show that the input operator works. std::istringstream iss("One"); TestEnum::type value = TestEnum::Zero; // We expect this to work. iss >> value; if (iss.fail()) { std::cout << "Failed to convert 'One' to TestEnum::type... fail" << std::endl; } else { std::cout << "Successfully converted 'One' to TestEnum::type: " << value << "... ok" << std::endl; } } catch (...) { std::cout << "Unknown exception caught converting 'One' to TestEnum... fail" << std::endl; } try { // Show that invalid input set the fail bit on the input stream and no // exception is thrown, since we did not enable them on the stream. std::istringstream iss("Two"); TestEnum::type value = TestEnum::Zero; // We expect this to fail. iss >> value; if (iss.fail()) { std::cout << "Failed to convert 'Two' to TestEnum::type... ok" << std::endl; } else { std::cout << "Successfully converted 'Two' to TestEnum::type: " << value << "... fail" << std::endl; } } catch (...) { std::cout << "Unknown exception caught converting 'Two' to TestEnum... fail" << std::endl; } try { // Show that setting the input stream to throw on failure currently // results in a JS exception being emitted. std::istringstream iss("Three"); TestEnum::type value = TestEnum::Zero; // Tell the stream to throw on failure. iss.exceptions(std::ios_base::failbit); // We expect this to fail. iss >> value; if (iss.fail()) { std::cout << "No exception thrown; Failed to convert 'Three' to TestEnum::type..." "fail" << std::endl; } else { std::cout << "Successfully converted 'Three' to TestEnum::type: " << value << "... fail" << std::endl; } } catch(const std::ios_base::failure& ex) { std::cout << "Caught exception: " << ex.what() << "... ok" << std::endl; } catch (...) { std::cout << "Unknown exception caught converting 'Three' to TestEnum... fail" << std::endl; } return 0; }