1 ///////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
5 // This code is licensed under the MIT License (MIT).
7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15 ///////////////////////////////////////////////////////////////////////////////
19 #include <gsl/gsl_assert> // for Expects
20 #include <gsl/gsl_util> // for narrow_cast
23 struct narrowing_error : public std::exception
25 const char* what() const noexcept override
27 return "narrowing_error";
31 // narrow() : a checked version of narrow_cast() that throws if the cast changed the value
32 template <class T, class U>
33 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
34 GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
36 T narrow(U u) noexcept(false)
38 constexpr const bool is_different_signedness = (std::is_signed<T>::value != std::is_signed<U>::value);
40 const T t = narrow_cast<T>(u);
42 if (static_cast<U>(t) != u
43 || (is_different_signedness
44 && ((t < T{}) != (u < U{}))))
46 throw narrowing_error{};
52 #endif // GSL_NARROW_H