// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #if !defined __GNUC__ #pragma warning( disable: 4571 4820 4514 4987 4710 4309 4986 4548 4189 4866) // relative include path contains '..' // (function) selected for automatic inline expansion #pragma warning( disable: 4464 4711 ) #else #pragma GCC diagnostic ignored "-Wunused-variable" #endif #include "../SafeInt.hpp" void ConstExpr(); enum class Foo { Foo1 = 0, Foo2 }; template void ModulusFriendTest() { U u = 3; SafeInt st(1); T t = u % st; } template void CompiledMixedType() { // Mixed constructors U u = 0; T t = 0; bool b = false; SafeInt st(u); SafeInt su(u); SafeInt st2(su); // Shut up the compiler b = !b; // Assignment st = t; st = u; st = su; st = st2; // Casting U u2 = (U)st; // Multiplication t = st * u; t = st * st2; t = u * st; st *= u; st *= su; // Modulus, modulus assignment u = 1; st = 1; su = 1; // For some reason, this is annoying the VS17 link time code generation // t = u % st; t = st % u; st2 = 1; t = st % st2; st %= u; st %= su; // Division u = 1; st2 = 1; st = 1; t = st / u; t = st / st2; t = u / st; st /= u; st /= su; // Addition t = st + u; t = st + st2; t = u + st; st += u; st += su; // Subtraction st = 0; u = 0; st2 = 0; t = st - u; t = st - st2; t = u - st; st -= u; st = 1; su = 1; st -= su; // Shift operators u = 1; su = 1; // Left t = st << u; t = st << su; t = t << su; st <<= u; st <<= su; // Right t = st >> u; t = st >> su; t = t >> su; st >>= u; st >>= su; // Binary operations // And t = st & st2; t = st & u; t = t & su; st &= st2; st &= u; st &= su; // Or t = st | st2; t = st | u; t = t | su; st |= st2; st |= u; st |= su; // Xor t = st ^ st2; t = st ^ u; t = t ^ su; st ^= st2; st ^= u; st ^= su; // Comparisons // Less than b = st < su; b = st < u; b = u < st; b = st < su; // Less than or equal b = st <= su; b = st <= u; b = u <= st; b = st <= su; // Greater than b = st > su; b = st > u; b = u > st; b = st > su; // Greater than or equal b = st >= su; b = st >= u; b = u >= st; b = st >= su; // Equals b = st == su; b = st == u; b = u == st; b = st == su; } template void CompileSigned() { SafeInt st; T t = -st; } template void CompileType() { // Test constructors SafeInt s; SafeInt i(Foo::Foo1); T t = 0; SafeInt st(t); SafeInt sb(false); // Mixed operations CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); CompiledMixedType(); // This is making trouble for the compiler ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); ModulusFriendTest(); // Special case casts bool b = (bool)s; wchar_t w = (wchar_t)s; size_t size = (size_t)s; float f = (float)s; double d = (double)s; long double ld = (long double)s; // Pointer operations T* p1 = s.Ptr(); const T* p2 = s.Ptr(); const T& r = s.Ref(); T* p3 = &s; const T* p4 = &s; // Unary operators bool b2 = !st; t = +st; st++; ++st; st--; --st; t = ~st; // Get compile time coverage of negation T x = 1; T result; (void)SafeNegation(x, result); } void MoveRegression() { #if CPLUSPLUS_STD == CPLUSPLUS_17 #include #include template class Union { public: Union() = default; Union& operator=(Union&&) noexcept = default; template Union& operator=(F&& t) { value = std::forward(t); return *this; } std::variant value; }; Union> x; Union> y; x = std::move(y); #endif } void CompileMe() { CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileType(); CompileSigned(); CompileSigned(); CompileSigned(); CompileSigned(); CompileSigned(); MoveRegression(); } /* Need to add tests for the miscellaneous helper functions Min, Max, Align, Swap Also need the pointer functions */ int main(int, char**) { CompileMe(); void ConstExpr(); return 0; }