티스토리 뷰

카테고리 없음

filamant c++ 관련 (2)

newpolaris 2021. 3. 18. 00:18

enable_if_arithmetic_t 으로 체크

enable 구문에 따른 오류 출력

#include <cstdint>
#include <cstddef>
#include <type_traits>

#ifdef _MSC_VER
#   define MATH_EMPTY_BASES __declspec(empty_bases)
#else
#   define MATH_EMPTY_BASES
#endif

template<typename A>
using enable_if_arithmetic_t = std::enable_if_t<std::is_arithmetic<A>::value>;

template <typename T> struct TVecAdd {};
template <typename T> struct TVecMul {};

template <typename T>
class MATH_EMPTY_BASES TVec4 : public TVecAdd<T>, TVecMul<T>
{
public:
    typedef T value_type;
    static constexpr size_t SIZE = 4;
    union {
        T v[SIZE];
        struct {
            union { T x; };
            union {
                struct {
                    union { T y; };
                    union {
                        struct { T z, w; };
                    };
                };
            };
        };
    };

    TVec4() noexcept = default;

    template<typename A, typename = enable_if_arithmetic_t<A>>
    constexpr TVec4(A v) noexcept : v{ T(v), T(v), T(v), T(v) } {}
};
static_assert(sizeof(TVec4<float>) == 4*sizeof(float), "size error");

using vec4f = TVec4<float>;

struct A {};

int main()
{
    constexpr vec4f v1 {};
    constexpr vec4f v2 { 0.1f };
    constexpr vec4f v3(v1);
    constexpr vec4f v4(A{});
    return 0;
}

enable 체크 구문이 없을 경우,

Cannot convert 'A' to 'float' without a conversion operator
Constexpr variable 'v4' must be initialized by a constant expression

있을 경우, 오버로딩 후보에서 탈락함에 따라

좀더 명확한 에러가 표시됨

No matching constructor for initialization of 'const vec4f' (aka 'const TVec4<float>')

is_arithmetic 의 구현

filament의 half float type 쪽 문제가 있나봄

// MSVC 2019 16.4 doesn't seem to like it when we specialize std::is_arithmetic for
// filament::math::half, so we're forced to create our own is_arithmetic here and specialize it
// inside of half.h.
template<typename T>
struct is_arithmetic : std::integral_constant<bool,
        std::is_integral<T>::value || std::is_floating_point<T>::value> {
};

template<> struct is_arithmetic<filament::math::half> : public std::true_type {};

namespace std {

template<> struct is_floating_point<filament::math::half> : public std::true_type {};

// note: this shouldn't be needed (is_floating_point<> is enough) but some version of msvc need it
// This stopped working with MSVC 2019 16.4, so we specialize our own version of is_arithmetic in
// the math::filament namespace (see above).
template<> struct is_arithmetic<filament::math::half> : public std::true_type {};

}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크