#pragma once
#include <cstddef> //4 size_t
#include <numeric> //4 max numbers
// узнать какая разрядность:
#define is_x64 __x86_64__
#define is_x32 __i386__
// узнать какая ОС:
#if (defined(_WIN32) || defined(_WIN64) || defined(WINDOWS) || defined(_WINDOWS))
  #define is_windows 1
#elif (defined(__linux__) || defined(linux) || defined(__linux))
  #define is_linux 1
#endif
// разделители файловых систем:
#ifdef is_windows
  #define SEPARATOR '\\'
  #define NSEPARATOR '/'
#else // LINUX
  #define SEPARATOR '/'
  #define NSEPARATOR '\\'
#endif
///! макрос для удаления и зануления ссылок
#define zdelete(ptr) \
if (ptr) { \
  delete ptr; \
  ptr = nullptr; \
}
///! удаляет массив
#define zdelete_arr(ptr) \
if (ptr) { \
  delete[] ptr; \
  ptr = nullptr; \
}
using index_t = std::size_t;
///! удаляет массив с ссылками и их объекты
#define zdelete_ptr_arr(ptr, size) \
if (ptr) { \
  for (index_t i = 0; i < size; ++i) \
    if (ptr[i]) \
      delete ptr[i]; \
  delete[] ptr; \
  ptr = nullptr; \
}
///! макрос для очистки массивов ссылок
#define vp_delete(vec) { \
  for (auto& it: vec) \
    if (it) { \
      delete it; \
      it = nullptr; \
    } \
  vec.clear(); \
}
#define rcast(type1, val) reinterpret_cast<type1>(val)
#define dcast(type1, val) dynamic_cast<type1>(val)
#define constx constexpr static const
#define CN(type) const type&
#define CP(type) const type*
#define cauto const auto
#define cnauto const auto&
#define nauto auto&
#define FOR(index_name, maximum) \
for (auto index_name = decltype(maximum){0}; index_name < maximum; ++index_name)
namespace a83 {
constexpr void invert(bool& val) { val = !val; }
} // a83 ns
template <typename T>
auto set_flag_if(bool cond, T& status, T flag) -> bool {
  if (cond) {
    status |= flag;
    return true;
  }
  status &= ~flag;
  return false;
} // set_flag_if
using uint = unsigned;
#define num_max(type) std::numeric_limits<type>::max()
#define num_min(type) std::numeric_limits<type>::min()
#define get_max_prec(type) std::numeric_limits<type>::digits10
#define float_inf std::numeric_limits<float>::infinity()
//! макрос для классов запрещающий копирование
#define nocopy(class_name) \
class_name(CN(class_name)) = delete; \
class_name& operator = (CN(class_name)) = delete
