aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax_utils.h
blob: d3d4a19606477a4d135ebb742c7b687e2ed9adcc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef EAX_UTILS_INCLUDED
#define EAX_UTILS_INCLUDED

#include <algorithm>
#include <cstdint>
#include <string>
#include <type_traits>


struct EaxAlLowPassParam
{
    float gain;
    float gain_hf;
}; // EaxAlLowPassParam


void eax_log_exception(
    const char* message = nullptr) noexcept;


template<
    typename TException,
    typename TValue
>
void eax_validate_range(
    const char* value_name,
    const TValue& value,
    const TValue& min_value,
    const TValue& max_value)
{
    if (value >= min_value && value <= max_value)
    {
        return;
    }

    const auto message =
        std::string{value_name} +
        " out of range (value: " +
        std::to_string(value) + "; min: " +
        std::to_string(min_value) + "; max: " +
        std::to_string(max_value) + ").";

    throw TException{message.c_str()};
}


namespace detail
{


template<
    typename T
>
struct EaxIsBitFieldStruct
{
private:
    using yes = std::true_type;
    using no = std::false_type;

    template<
        typename U
    >
    static auto test(int) -> decltype(std::declval<typename U::EaxIsBitFieldStruct>(), yes{});

    template<
        typename
    >
    static no test(...);


public:
    static constexpr auto value = std::is_same<decltype(test<T>(0)), yes>::value;
}; // EaxIsBitFieldStruct


template<
    typename T,
    typename TValue
>
inline bool eax_bit_fields_are_equal(
    const T& lhs,
    const T& rhs) noexcept
{
    static_assert(sizeof(T) == sizeof(TValue), "Invalid type size.");

    return reinterpret_cast<const TValue&>(lhs) == reinterpret_cast<const TValue&>(rhs);
}


} // namespace detail


template<
    typename T,
    std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
>
inline bool operator==(
    const T& lhs,
    const T& rhs) noexcept
{
    using Value = std::conditional_t<
        sizeof(T) == 1,
        std::uint8_t,
        std::conditional_t<
            sizeof(T) == 2,
            std::uint16_t,
            std::conditional_t<
                sizeof(T) == 4,
                std::uint32_t,
                void
            >
        >
    >;

    static_assert(!std::is_same<Value, void>::value, "Unsupported type.");

    return detail::eax_bit_fields_are_equal<T, Value>(lhs, rhs);
}

template<
    typename T,
    std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
>
inline bool operator!=(
    const T& lhs,
    const T& rhs) noexcept
{
    return !(lhs == rhs);
}


#endif // !EAX_UTILS_INCLUDED