1 /**
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 // -*- c++ -*-
9 
10 #ifndef FAISS_ASSERT_INCLUDED
11 #define FAISS_ASSERT_INCLUDED
12 
13 #include <faiss/impl/FaissException.h>
14 #include <faiss/impl/platform_macros.h>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <string>
18 
19 ///
20 /// Assertions
21 ///
22 
23 #define FAISS_ASSERT(X)                                  \
24     do {                                                 \
25         if (!(X)) {                                      \
26             fprintf(stderr,                              \
27                     "Faiss assertion '%s' failed in %s " \
28                     "at %s:%d\n",                        \
29                     #X,                                  \
30                     __PRETTY_FUNCTION__,                 \
31                     __FILE__,                            \
32                     __LINE__);                           \
33             abort();                                     \
34         }                                                \
35     } while (false)
36 
37 #define FAISS_ASSERT_MSG(X, MSG)                         \
38     do {                                                 \
39         if (!(X)) {                                      \
40             fprintf(stderr,                              \
41                     "Faiss assertion '%s' failed in %s " \
42                     "at %s:%d; details: " MSG "\n",      \
43                     #X,                                  \
44                     __PRETTY_FUNCTION__,                 \
45                     __FILE__,                            \
46                     __LINE__);                           \
47             abort();                                     \
48         }                                                \
49     } while (false)
50 
51 #define FAISS_ASSERT_FMT(X, FMT, ...)                    \
52     do {                                                 \
53         if (!(X)) {                                      \
54             fprintf(stderr,                              \
55                     "Faiss assertion '%s' failed in %s " \
56                     "at %s:%d; details: " FMT "\n",      \
57                     #X,                                  \
58                     __PRETTY_FUNCTION__,                 \
59                     __FILE__,                            \
60                     __LINE__,                            \
61                     __VA_ARGS__);                        \
62             abort();                                     \
63         }                                                \
64     } while (false)
65 
66 ///
67 /// Exceptions for returning user errors
68 ///
69 
70 #define FAISS_THROW_MSG(MSG)                                   \
71     do {                                                       \
72         throw faiss::FaissException(                           \
73                 MSG, __PRETTY_FUNCTION__, __FILE__, __LINE__); \
74     } while (false)
75 
76 #define FAISS_THROW_FMT(FMT, ...)                              \
77     do {                                                       \
78         std::string __s;                                       \
79         int __size = snprintf(nullptr, 0, FMT, __VA_ARGS__);   \
80         __s.resize(__size + 1);                                \
81         snprintf(&__s[0], __s.size(), FMT, __VA_ARGS__);       \
82         throw faiss::FaissException(                           \
83                 __s, __PRETTY_FUNCTION__, __FILE__, __LINE__); \
84     } while (false)
85 
86 ///
87 /// Exceptions thrown upon a conditional failure
88 ///
89 
90 #define FAISS_THROW_IF_NOT(X)                          \
91     do {                                               \
92         if (!(X)) {                                    \
93             FAISS_THROW_FMT("Error: '%s' failed", #X); \
94         }                                              \
95     } while (false)
96 
97 #define FAISS_THROW_IF_NOT_MSG(X, MSG)                       \
98     do {                                                     \
99         if (!(X)) {                                          \
100             FAISS_THROW_FMT("Error: '%s' failed: " MSG, #X); \
101         }                                                    \
102     } while (false)
103 
104 #define FAISS_THROW_IF_NOT_FMT(X, FMT, ...)                               \
105     do {                                                                  \
106         if (!(X)) {                                                       \
107             FAISS_THROW_FMT("Error: '%s' failed: " FMT, #X, __VA_ARGS__); \
108         }                                                                 \
109     } while (false)
110 
111 #endif
112