Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c192ad2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "stagefright/foundation: add AUnion and AData templates"

parents 3b6889c2 e322cc51
Loading
Loading
Loading
Loading
+843 −0

File added.

Preview size limit exceeded, changes collapsed.

+133 −0
Original line number Diff line number Diff line
@@ -85,6 +85,139 @@ struct is_unsigned_integral
            typename underlying_integral_type<T, signed>::type>::value> {
};

/**
 * Type support relationship query template.
 *
 * If T occurs as one of the types in Us with the same const-volatile qualifications, provides the
 * member constant |value| equal to true. Otherwise value is false.
 */
template<typename T, typename ...Us>
struct is_one_of;

/// \if 0
/**
 * Template specialization when first type matches the searched type.
 */
template<typename T, typename ...Us>
struct is_one_of<T, T, Us...> : std::true_type {};

/**
 * Template specialization when first type does not match the searched type.
 */
template<typename T, typename U, typename ...Us>
struct is_one_of<T, U, Us...> : is_one_of<T, Us...> {};

/**
 * Template specialization when there are no types to search.
 */
template<typename T>
struct is_one_of<T> : std::false_type {};
/// \endif

/**
 * Type support relationship query template.
 *
 * If all types in Us are unique, provides the member constant |value| equal to true.
 * Otherwise value is false.
 */
template<typename ...Us>
struct are_unique;

/// \if 0
/**
 * Template specialization when there are no types.
 */
template<>
struct are_unique<> : std::true_type {};

/**
 * Template specialization when there is at least one type to check.
 */
template<typename T, typename ...Us>
struct are_unique<T, Us...>
    : std::integral_constant<bool, are_unique<Us...>::value && !is_one_of<T, Us...>::value> {};
/// \endif

/// \if 0
template<size_t Base, typename T, typename ...Us>
struct _find_first_impl;

/**
 * Template specialization when there are no types to search.
 */
template<size_t Base, typename T>
struct _find_first_impl<Base, T> : std::integral_constant<size_t, 0> {};

/**
 * Template specialization when T is the first type in Us.
 */
template<size_t Base, typename T, typename ...Us>
struct _find_first_impl<Base, T, T, Us...> : std::integral_constant<size_t, Base> {};

/**
 * Template specialization when T is not the first type in Us.
 */
template<size_t Base, typename T, typename U, typename ...Us>
struct _find_first_impl<Base, T, U, Us...>
    : std::integral_constant<size_t, _find_first_impl<Base + 1, T, Us...>::value> {};

/// \endif

/**
 * Type support relationship query template.
 *
 * If T occurs in Us, index is the 1-based left-most index of T in Us. Otherwise, index is 0.
 */
template<typename T, typename ...Us>
struct find_first {
    static constexpr size_t index = _find_first_impl<1, T, Us...>::value;
};

/// \if 0
/**
 * Helper class for find_first_convertible_to template.
 *
 * Adds a base index.
 */
template<size_t Base, typename T, typename ...Us>
struct _find_first_convertible_to_helper;

/**
 * Template specialization for when there are more types to consider
 */
template<size_t Base, typename T, typename U, typename ...Us>
struct _find_first_convertible_to_helper<Base, T, U, Us...> {
    static constexpr size_t index =
        std::is_convertible<T, U>::value ? Base :
                _find_first_convertible_to_helper<Base + 1, T, Us...>::index;
    typedef typename std::conditional<
        std::is_convertible<T, U>::value, U,
        typename _find_first_convertible_to_helper<Base + 1, T, Us...>::type>::type type;
};

/**
 * Template specialization for when there are no more types to consider
 */
template<size_t Base, typename T>
struct _find_first_convertible_to_helper<Base, T> {
    static constexpr size_t index = 0;
    typedef void type;
};

/// \endif

/**
 * Type support template that returns the type that T can be implicitly converted into, and its
 * index, from a list of other types (Us).
 *
 * Returns index of 0 and type of void if there are no convertible types.
 *
 * \param T type that is converted
 * \param Us types into which the conversion is considered
 */
template<typename T, typename ...Us>
struct find_first_convertible_to : public _find_first_convertible_to_helper<1, T, Us...> { };

}  // namespace android

#endif  // STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_
+981 −0

File added.

Preview size limit exceeded, changes collapsed.

+2 −0
Original line number Diff line number Diff line
@@ -8,12 +8,14 @@ LOCAL_MODULE := sf_foundation_test
LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := \
	AData_test.cpp \
	Flagged_test.cpp \
	TypeTraits_test.cpp \
	Utils_test.cpp \

LOCAL_SHARED_LIBRARIES := \
	libstagefright_foundation \
	libutils \

LOCAL_C_INCLUDES := \
	frameworks/av/include \
+71 −0
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@ protected:

// =========== basic sanity tests for type-support templates
TEST_F(TypeTraitsTest, StaticTests) {

    // ============ is_integral_or_enum

    static_assert(!std::is_integral<A>::value, "enums should not be integral");
    static_assert(!std::is_integral<UA>::value, "enums should not be integral");
    static_assert(!std::is_integral<IA>::value, "enums should not be integral");
@@ -42,6 +45,8 @@ TEST_F(TypeTraitsTest, StaticTests) {
    static_assert(is_integral_or_enum<unsigned>::value, "unsigned ints should be integral_or_enum");
    static_assert(!is_integral_or_enum<float>::value, "floats should not be integral_or_enum");

    // ============ is_unsigned_integral

    static_assert(!std::is_unsigned<UA>::value,
                  "unsigned enums should not be unsigned");
    static_assert(!std::is_unsigned<IA>::value,
@@ -61,6 +66,8 @@ TEST_F(TypeTraitsTest, StaticTests) {
    static_assert(!is_unsigned_integral<float>::value,
                  "floats should not be unsigned_integral");

    // ============ is_signed_integral

    static_assert(!std::is_signed<UA>::value,
                  "unsigned enums should not be signed");
    static_assert(!std::is_signed<IA>::value,
@@ -80,6 +87,8 @@ TEST_F(TypeTraitsTest, StaticTests) {
    static_assert(!is_signed_integral<float>::value,
                  "floats should not be signed_integral");

    // ============ underlying_integral_type

    static_assert(std::is_same<uint64_t, typename underlying_integral_type<uint64_t>::type>::value,
                  "underlying integral type of uint64_t should be uint64_t");
    static_assert(std::is_same<uint32_t, typename underlying_integral_type<UA>::type>::value,
@@ -91,6 +100,68 @@ TEST_F(TypeTraitsTest, StaticTests) {
    //typedef underlying_integral_type<float>::type no_type;
    static_assert(std::is_same<void, typename underlying_integral_type<float, void>::type>::value,
                  "underlying integral type of float cannot be specified");

    // ============ is_one_of

    static_assert(!is_one_of<int>::value, "int shouldn't be one of {}");
    static_assert(!is_one_of<int, unsigned>::value, "int shouldn't be one of {unsigned}");
    static_assert(!is_one_of<int, unsigned, float>::value,
                  "int shouldn't be one of {unsigned, float}");
    static_assert(is_one_of<int, int>::value, "int should be one of {int}");
    static_assert(is_one_of<int, int, float>::value, "int should be one of {int, float}");
    static_assert(is_one_of<int, float, int>::value, "int should be one of {float, int}");
    static_assert(is_one_of<int, float, int, unsigned>::value,
                  "int should be one of {float, int, unsigned}");
    static_assert(is_one_of<int, float, unsigned, int>::value,
                  "int should be one of {float, unsigned, int}");
    static_assert(!is_one_of<int, int&>::value, "int shouldn't be one of {int&}");

    // ============ are_unique

    static_assert(are_unique<>::value, "{} should be unique");
    static_assert(are_unique<int>::value, "{int} should be unique");
    static_assert(are_unique<int, float>::value, "{int, float} should be unique");
    static_assert(!are_unique<int, int>::value, "{int, int} shouldn't be unique");
    static_assert(!are_unique<int, float, int>::value, "{int, float, int} shouldn't be unique");
    static_assert(!are_unique<float, int, int>::value, "{float, int, int} shouldn't be unique");
    static_assert(!are_unique<int, int, float>::value, "{int, int, float} shouldn't be unique");

    // ============ find_first

    static_assert(find_first<int>::index == 0, "int is not in {}");
    static_assert(find_first<int, unsigned>::index == 0, "int is not in {unsigned}");
    static_assert(find_first<int, unsigned, float>::index == 0, "int is not in {unsigned, float}");
    static_assert(find_first<int, int>::index == 1, "int is 1st in {int}");
    static_assert(find_first<int, int, float>::index == 1, "int is 1st in {int, float}");
    static_assert(find_first<int, float, int>::index == 2, "int is 2nd in {float, int}");
    static_assert(find_first<int, float, int, unsigned>::index == 2,
                  "int is 2nd in {float, int, unsigned}");
    static_assert(find_first<int, float, int, unsigned>::index == 2,
                  "int is 2nd and 3rd in {float, int, int, unsigned}");
    static_assert(find_first<int, float, unsigned, int>::index == 3,
                  "int is 3rd in {float, unsigned, int}");
    static_assert(find_first<int, int&>::index == 0, "int is not in {int&}");

    // ============ find_first_convertible_to

    static_assert(find_first_convertible_to<int>::index == 0, "int is not convertible to {}");
    static_assert(find_first_convertible_to<int, unsigned*>::index == 0,
                  "int is not convertible to {unsigned*}");
    static_assert(find_first_convertible_to<int, unsigned*, float&>::index == 0,
                  "int is not convertible to {unsigned, float&}");
    static_assert(find_first_convertible_to<int, int>::index == 1, "int is convertible to {int}");
    static_assert(find_first_convertible_to<int, unsigned, int>::index == 1,
                  "int is convertible to 1st of {unsigned, int}");
    static_assert(find_first_convertible_to<int, int&, float>::index == 2,
                  "int is convertible to 2nd of {int&, float}");
    static_assert(find_first_convertible_to<float, float*, int, unsigned>::index == 2,
                  "float is convertible to 2nd of {float*, int, unsigned}");
    static_assert(find_first_convertible_to<float, void, float[1], int>::index == 3,
                  "int is 3rd convertible to {void, float[], int}");
    static_assert(find_first_convertible_to<int&, const int&>::index == 1,
                  "int& is convertible to {const int&}");
    static_assert(find_first_convertible_to<const int&, int&>::index == 0,
                  "const int& is not convertible to {int&}");
}

} // namespace android