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 #define _QX_JOIN(symbol1, symbol2) _QX_DO_JOIN(symbol1, symbol2)
15 #define _QX_DO_JOIN(symbol1, symbol2) symbol1##symbol2
16 
17 /**
18  @def QX_EMPTY_MACRO
19  @brief Placeholder for disabled macros
20  @details Has no effect and work correctly with "if else"
21  You can use it in the end of a macro to enforce user to add ; after it
22 **/
23 #define QX_EMPTY_MACRO static_assert(true)
24 
25 /**
26  @brief Same as __LINE__, but fixes some problems when using it in constexpr context
27 **/
28 #define QX_LINE int(_QX_JOIN(__LINE__, U))
29 
30 
31 namespace qx::details
32 {
33 
34 constexpr const char_type* last_slash(const char_type* str)
35 {
36  const char_type* pszLastSlash = str;
37  while (str && *str != QX_TEXT('\0'))
38  {
39  if (*str == QX_TEXT('\\') || *str == QX_TEXT('/'))
40  pszLastSlash = str;
41 
42  ++str;
43  }
44  return pszLastSlash + 1;
45 }
46 
47 } // namespace qx::details
48 
49 /**
50  @def QX_SHORT_FILE
51  @brief Cuts full absolute path to the file name only
52  ex: "C:\folder1\foler2\file.h" => "file.h"
53 **/
54 #define QX_SHORT_FILE qx::details::last_slash(QX_TEXT(__FILE__))
55 
56 /**
57  @def QX_SINGLE_ARGUMENT
58  @brief Let macro param containing commas work fine
59  "#define FOO(type, name) type name"
60  FOO(QX_SINGLE_ARGUMENT(std::map<int, int>), map_var);
61  @param ... - param containing commas
62 **/
63 #define QX_SINGLE_ARGUMENT(...) __VA_ARGS__
64 
65 /**
66  @def QX_CONST_CAST_THIS
67  @brief This macro is made for situations where you have a const method and you need exactly the same method but non-const
68  @warning You can also use it in vice-versa situations, but be careful as it will break your const guarantees
69 
70  @code
71  int foo() const
72  {
73  // some complicated stuff
74  }
75  int foo()
76  {
77  QX_CONST_CAST_THIS()->foo();
78  }
79  @endcode
80 **/
81 #define QX_CONST_CAST_THIS() const_cast<qx::switch_const_t<std::remove_pointer_t<decltype(this)>>*>(this)
82 
83 namespace qx::details
84 {
85 
86 template<class lambda_type>
88 {
89 public:
90  call_before_main_invoker(lambda_type lambda) : m_Lambda(std::move(lambda))
91  {
92  m_Lambda();
93  }
94 
95 private:
96  lambda_type m_Lambda;
97 };
98 
99 } // namespace qx::details
100 
101 /**
102  @def QX_CALL_BEFORE_MAIN
103  @brief Calls this lambda before the main invocation
104  @note This function must be in an object file, that is actually linked to your exe
105 
106  @code
107  QX_CALL_BEFORE_MAIN = []()
108  {
109  };
110  @endcode
111 **/
112 #define QX_CALL_BEFORE_MAIN inline volatile qx::details::call_before_main_invoker QX_LINE_NAME(_stubCallBeforeMain)
113 
114 #if QX_MSVC
115  #define QX_DISABLE_OPTIMIZATIONS() __pragma(optimize("", off))
116  #define QX_ENABLE_OPTIMIZATIONS() __pragma(optimize("", on))
117 #else
118  #define QX_DISABLE_OPTIMIZATIONS()
119  #define QX_ENABLE_OPTIMIZATIONS()
120 #endif