#include #include #include #include #include #include #include template T& negate(T& value); namespace details { void negate(bool& value, int, int) { value = !value; } template auto negate(T& value, int, int) -> std::enable_if_t> { value = -value; } template auto negate(T& str, int, int)-> std::enable_if_t> { std::reverse(std::begin(str), std::end(str)); } template auto negate(Container& container, int, float) -> decltype(std::begin(container), std::declval()) { for (auto&& element : container) ::negate(element); } template void negate(T& value, float, float) { value = ~value; } } template T& negate(T& value) { details::negate(value, 0, 0); return value; } int main() { // signed value double n { 1.0 }; assert(negate(n) == -1.0); // bool value bool b { true }; assert(negate(b) == false); // bitwise negation unsigned u { 2196674553u }; assert(negate(u) == 2098292742u); // string std::string s { "drawer" }; assert(negate(s) == "reward"); // container std::vector v { 1, -2, 3, -4 }; assert(( negate(v) == std::vector{ -1, 2, -3, 4 } )); // recursive container case std::vector> r { std::deque{ "bat", "brag" }, std::deque{ "flow", "loop" } }; std::vector> result { std::deque{ "tab", "garb" }, std::deque{ "wolf", "pool" } }; assert(negate(r) == result); // C-array case int a[] { 6, -4, 0, 5 }; negate(a); assert(a[0] == -6); assert(a[1] == 4); assert(a[2] == 0); assert(a[3] == -5); }