1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include <boost/preprocessor/facilities/overload.hpp> 34 #include <string> 35 36 #include "mongo/platform/compiler.h" 37 #include "mongo/util/debug_util.h" 38 39 namespace mongo { 40 41 /** 42 * This include exists so that mongo/base/status_with.h can use the invariant macro without causing 43 * a circular include chain. It should never be included directly in any other file other than that 44 * one (and assert_util.h). 45 */ 46 47 #if !defined(MONGO_INCLUDE_INVARIANT_H_WHITELISTED) 48 #error "Include assert_util.h instead of invariant.h." 49 #endif 50 51 MONGO_COMPILER_NORETURN void invariantFailed(const char* expr, 52 const char* file, 53 unsigned line) noexcept; 54 55 // This overload is our legacy invariant, which just takes a condition to test. 56 // 57 // ex) invariant(!condition); 58 // 59 // Invariant failure !condition some/file.cpp 528 60 // 61 #define MONGO_invariant_1(_Expression) \ 62 do { \ 63 if (MONGO_unlikely(!(_Expression))) { \ 64 ::mongo::invariantFailed(#_Expression, __FILE__, __LINE__); \ 65 } \ 66 } while (false) 67 68 MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr, 69 const char* msg, 70 const char* file, 71 unsigned line) noexcept; 72 73 MONGO_COMPILER_NORETURN void invariantFailedWithMsg(const char* expr, 74 const std::string& msg, 75 const char* file, 76 unsigned line) noexcept; 77 78 // This invariant overload accepts a condition and a message, to be logged if the condition is 79 // false. 80 // 81 // ex) invariant(!condition, "hello!"); 82 // 83 // Invariant failure !condition "hello!" some/file.cpp 528 84 // 85 #define MONGO_invariant_2(_Expression, _Message) \ 86 do { \ 87 if (MONGO_unlikely(!(_Expression))) { \ 88 ::mongo::invariantFailedWithMsg(#_Expression, (_Message), __FILE__, __LINE__); \ 89 } \ 90 } while (false) 91 92 // This helper macro is necessary to make the __VAR_ARGS__ expansion work properly on MSVC. 93 #define MONGO_expand(x) x 94 95 #define invariant(...) \ 96 MONGO_expand(MONGO_expand(BOOST_PP_OVERLOAD(MONGO_invariant_, __VA_ARGS__))(__VA_ARGS__)) 97 98 // Behaves like invariant in debug builds and is compiled out in release. Use for checks, which can 99 // potentially be slow or on a critical path. 100 #define MONGO_dassert(...) \ 101 if (kDebugBuild) \ 102 invariant(__VA_ARGS__) 103 104 #define dassert MONGO_dassert 105 106 } // namespace mongo 107