diff --git a/AK/StdLibExtras.h b/AK/StdLibExtras.h index 67c0f865a48..989aba9d5c8 100644 --- a/AK/StdLibExtras.h +++ b/AK/StdLibExtras.h @@ -107,10 +107,12 @@ template struct RemoveConst { typedef T Type; }; + template struct RemoveConst { typedef T Type; }; + template struct RemoveVolatile { typedef T Type; @@ -441,6 +443,22 @@ inline constexpr T exchange(T& slot, U&& value) return old_value; } +template +struct IsUnion : public IntegralConstant { +}; + +template +struct IsClass : public IntegralConstant { +}; + +template +struct IsBaseOf : public IntegralConstant { +}; + +template +using CopyConst = + typename Conditional::value, typename AddConst::Type, typename RemoveConst::Type>::Type; + } using AK::AddConst; @@ -449,8 +467,11 @@ using AK::clamp; using AK::Conditional; using AK::exchange; using AK::forward; +using AK::IsBaseOf; +using AK::IsClass; using AK::IsConst; using AK::IsSame; +using AK::IsUnion; using AK::IsVoid; using AK::MakeSigned; using AK::MakeUnsigned; diff --git a/AK/TypeCasts.h b/AK/TypeCasts.h new file mode 100644 index 00000000000..434da021e6f --- /dev/null +++ b/AK/TypeCasts.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in input and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of input code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace AK { + +template::value> +struct TypeTraits { + static bool has_type(InputType&) + { + static_assert(IsVoid::value, "No TypeTraits for this type"); + return false; + } +}; + +template +struct TypeTraits { + static bool has_type(InputType&) { return true; } +}; + +template +inline bool is(InputType* input) +{ + return input && TypeTraits::has_type(*input); +} + +template +inline bool is(InputType& input) +{ + return TypeTraits::has_type(input); +} + +template +inline CopyConst* downcast(InputType* input) +{ + static_assert(IsBaseOf::value); + ASSERT(!input || is(*input)); + return static_cast*>(input); +} + +template +inline CopyConst& downcast(InputType& input) +{ + static_assert(IsBaseOf::value); + ASSERT(is(input)); + return static_cast&>(input); +} + +#define AK_BEGIN_TYPE_TRAITS(ClassName) \ + namespace AK { \ + template \ + class TypeTraits { \ + public: \ + static bool has_type(InputType& input) { return is_type(input); } \ + \ + private: + +#define AK_END_TYPE_TRAITS() \ + } \ + ; \ + } + +} + +using AK::downcast; +using AK::is; +using AK::TypeTraits;