#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 #define SAW_ASSERT(expression) \ assert(expression); \ if (!(expression)) 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 ReturnTypeHelper { typedef decltype(instance()(instance())) Type; }; template struct ReturnTypeHelper { typedef decltype(instance()()) Type; }; template using ReturnType = typename ReturnTypeHelper::Type; struct Void {}; template struct VoidFix { typedef T Type; }; template <> struct VoidFix { typedef Void Type; }; template using FixVoid = typename VoidFix::Type; template struct VoidUnfix { typedef T Type; }; template <> struct VoidUnfix { typedef void Type; }; template using UnfixVoid = typename VoidUnfix::Type; } // namespace saw