#pragma once #include #include #include #include namespace saw { #define SAW_CONCAT_(x, y) x##y #define SAW_CONCAT(x, y) SAW_CONCAT_(x, y) #define SAW_UNIQUE_NAME(prefix) SAW_CONCAT(prefix, __LINE__) #define SAW_FORBID_COPY(classname) \ classname(const classname &) = delete; \ classname &operator=(const classname &) = delete #define SAW_FORBID_MOVE(classname) \ classname(classname &&) = delete; \ classname &operator=(classname &&) = delete #define SAW_DEFAULT_COPY(classname) \ classname(const classname &) = default; \ classname &operator=(const classname &) = default #define SAW_DEFAULT_MOVE(classname) \ classname(classname &&) = default; \ classname &operator=(classname &&) = default // In case of C++20 #define SAW_ASSERT(expression) \ assert(expression); \ if (!(expression)) [[unlikely]] template using maybe = std::optional; template using own = std::unique_ptr; template using our = std::shared_ptr; template using lent = std::weak_ptr; template own heap(Args &&...args) { return own(new T(std::forward(args)...)); } template our share(Args &&...args) { return std::make_shared(std::forward(args)...); } template T instance() noexcept; template struct return_type_helper { typedef decltype(instance()(instance())) Type; }; template struct return_type_helper { typedef decltype(instance()()) Type; }; template using return_type = typename return_type_helper::Type; struct void_t {}; template struct void_fix { typedef T Type; }; template <> struct void_fix { typedef void_t Type; }; template using fix_void = typename void_fix::Type; template struct void_unfix { typedef T Type; }; template <> struct void_unfix { typedef void Type; }; template using unfix_void = typename void_unfix::Type; template constexpr bool always_false = false; } // namespace saw