qxLib
common.h
Go to the documentation of this file.
1 /**
2 
3  @file common.h
4  @author Khrapov
5  @date 17.06.2019
6  @copyright © Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 #pragma once
10 
12 #include <qx/meta/qualifiers.h>
13 
14 /**
15  @def QX_EMPTY_MACRO
16  @brief Placeholder for disabled macros
17  @details Has no effect and work correctly with "if else"
18  You can use it in the end of a macro to enforce user to add ; after it
19 **/
20 #define QX_EMPTY_MACRO static_assert(true)
21 
22 /**
23  @def QX_STRINGIFY
24  @brief Macro can be used to turn any text in your code into a string,
25  but only the exact text between the parentheses
26  There are no variable dereferencing or macro substitutions or any other sort of thing done.
27  @param name - name to convert to the string
28 **/
29 #define QX_STRINGIFY(name) #name
30 
31 #define _QX_JOIN(symbol1, symbol2) _QX_DO_JOIN(symbol1, symbol2)
32 #define _QX_DO_JOIN(symbol1, symbol2) symbol1##symbol2
33 
34 /**
35  @def QX_LINE_NAME
36  @brief Do magic! Creates a unique name using the line number
37  @param prefix - name prefix
38 **/
39 #define QX_LINE_NAME(prefix) _QX_JOIN(prefix, __LINE__)
40 
41 /**
42  @brief Same as __LINE__, but fixes some problems when using it in constexpr context
43 **/
44 #define QX_LINE int(_QX_JOIN(__LINE__, U))
45 
46 
47 namespace qx::details
48 {
49 
50 constexpr const char_type* last_slash(const char_type* str)
51 {
52  const char_type* pszLastSlash = str;
53  while (str && *str != QX_TEXT('\0'))
54  {
55  if (*str == QX_TEXT('\\') || *str == QX_TEXT('/'))
56  pszLastSlash = str;
57 
58  ++str;
59  }
60  return pszLastSlash + 1;
61 }
62 
63 } // namespace qx::details
64 
65 /**
66  @def QX_SHORT_FILE
67  @brief Cuts full absolute path to the file name only
68  ex: "C:\folder1\foler2\file.h" => "file.h"
69 **/
70 #define QX_SHORT_FILE qx::details::last_slash(QX_TEXT(__FILE__))
71 
72 /**
73  @def QX_SINGLE_ARGUMENT
74  @brief Let macro param containing commas work fine
75  "#define FOO(type, name) type name"
76  FOO(QX_SINGLE_ARGUMENT(std::map<int, int>), map_var);
77  @param ... - param containing commas
78 **/
79 #define QX_SINGLE_ARGUMENT(...) __VA_ARGS__
80 
81 /**
82  @def QX_CONST_CAST_THIS
83  @brief This macro is made for situations where you have a const method and you need exactly the same method but non-const
84  @warning You can also use it in vice-versa situations, but be careful as it will break your const guarantees
85 
86  @code
87  int foo() const
88  {
89  // some complicated stuff
90  }
91  int foo()
92  {
93  QX_CONST_CAST_THIS()->foo();
94  }
95  @endcode
96 **/
97 #define QX_CONST_CAST_THIS() const_cast<qx::switch_const_t<std::remove_pointer_t<decltype(this)>>*>(this)
98 
99 namespace qx::details
100 {
101 
102 template<class lambda_type>
104 {
105 public:
106  call_before_main_invoker(lambda_type lambda) : m_Lambda(std::move(lambda))
107  {
108  m_Lambda();
109  }
110 
111 private:
112  lambda_type m_Lambda;
113 };
114 
115 } // namespace qx::details
116 
117 /**
118  @def QX_CALL_BEFORE_MAIN
119  @brief Calls this lambda before the main invocation
120  @note This function must be in an object file, that is actually linked to your exe
121 
122  @code
123  QX_CALL_BEFORE_MAIN = []()
124  {
125  };
126  @endcode
127 **/
128 #define QX_CALL_BEFORE_MAIN inline volatile qx::details::call_before_main_invoker QX_LINE_NAME(_stubCallBeforeMain)
129 
130 #if QX_MSVC
131  #define QX_DISABLE_OPTIMIZATIONS() __pragma(optimize("", off))
132  #define QX_ENABLE_OPTIMIZATIONS() __pragma(optimize("", on))
133 #else
134  #define QX_DISABLE_OPTIMIZATIONS()
135  #define QX_ENABLE_OPTIMIZATIONS()
136 #endif