Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * yk_essentials.hpp
- *
- * @author Peter Lenkefi
- * @date 2019-03-19
- * @description Things that make coding in C++ cleaner/easier.
- */
- #ifndef YK_ESSENTIALS_HPP
- #define YK_ESSENTIALS_HPP
- #include <cstddef>
- #include <type_traits>
- #include "yk_preproc.hpp"
- /**
- * First we assert the language.
- */
- #if yk_pp_lang != yk_pp_cpp
- # error "The essentials header may only be used with a C++ compiler!"
- #endif
- /**
- * At least C++11.
- */
- #if yk_pp_standard < yk_pp_11
- # error "The essentials header requires a C++11 compiler or newer!"
- #endif
- /**
- * Based on standard version.
- */
- #if yk_pp_standard >= yk_pp_14
- # define yk_constexpr_14 constexpr
- #else
- # define yk_constexpr_14
- #endif
- namespace yk {
- /**
- * Simplifies concept checking with a nicer message.
- *
- * Example usage:
- * template <typename Range>
- * struct foo {
- * yk_assert_concept(is_range_v<Range>);
- * };
- *
- * If the assertion fails, the error message is:
- * "Concept assertion is_range_v<Range> failed!"
- */
- #define yk_assert_concept(...) \
- static_assert(__VA_ARGS__, "Concept assertion " #__VA_ARGS__ " failed!")
- /**
- * Constrains a function to a condition.
- *
- * Example usage:
- * template <std::size_t N>
- * struct vec {
- * yk_requires(N == 3)
- * auto cross(vec const& o) { ... }
- * };
- */
- #define yk_requires(...) \
- template <yk_requires_t(__VA_ARGS__)>
- /**
- * Constraints a function to a condition in a template.
- *
- * Example usage:
- * template <typename R, yk_requires_t(is_range_v<R>)>
- * void for_each(R&& r) { ... }
- */
- #define yk_requires_t(...) \
- yk_prelude_requires_t1(yk_pp_unique_id(concept_req), __VA_ARGS__)
- #define yk_prelude_requires_t1(id, ...) \
- bool id = false, \
- ::std::enable_if_t<id || (__VA_ARGS__), ::std::nullptr_t> = nullptr
- /**
- * A macro to create a new tag-type.
- */
- namespace detail {
- template <typename>
- struct tag_type {};
- } /* namespace detail */
- #define yk_create_tag_type() \
- ::yk::detail::tag_type<struct yk_pp_unique_id(tag_type_param)>
- /**
- * A macro that helps forwarding in the trivial case.
- *
- * Example usage:
- * template <typename TFwd>
- * void foo(T&& arg) {
- * bar(yk_fwd(arg));
- * }
- */
- #define yk_fwd(...) \
- ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
- /**
- * Utility for CRTP-based code.
- * Removes the need for casting to underlying type with the provided self()
- * member functions. It's important to call them with this->self() to avoid
- * name resolving errors.
- *
- * It can be used to inject extra functionality (like metaclasses). See the
- * example below.
- *
- * Example usage:
- * template <typename Self>
- * class foo_base : public crtp<Self> {
- * public:
- * int bar() {
- * return this->self().baz() * 2;
- * }
- * };
- *
- * class foo : public foo_base<foo> {
- * public:
- * int baz() { return 1; }
- * };
- *
- * // foo has a function called bar() too
- */
- using crtp_default_tag = yk_create_tag_type();
- template <typename Self, typename Tag = crtp_default_tag>
- class crtp {
- public:
- using self_type = Self;
- [[nodiscard]]
- yk_constexpr_14 self_type& self() noexcept {
- return static_cast<self_type&>(*this);
- }
- [[nodiscard]]
- yk_constexpr_14 self_type const& self() const noexcept {
- return static_cast<self_type const&>(*this);
- }
- };
- } /* namespace yk */
- #undef yk_constexpr_14
- #endif /* YK_ESSENTIALS_HPP */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement