C2.h revision 29a6ba9949e4127a9c6df2cc75033dbe97f501a9
129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/*
229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Copyright (C) 2016 The Android Open Source Project
329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * you may not use this file except in compliance with the License.
629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * You may obtain a copy of the License at
729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
1029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Unless required by applicable law or agreed to in writing, software
1129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * See the License for the specific language governing permissions and
1429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * limitations under the License.
1529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
1629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
1729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#ifndef C2_H_
1829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_H_
1929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
2029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <string>
2129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <vector>
2229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <list>
2329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
2429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#ifdef __ANDROID__
2529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
2629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <utils/Errors.h>       // for status_t
2729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <utils/Timers.h>       // for nsecs_t
2829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
2929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarnamespace android {
3029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
3129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#else
3229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
3329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#include <errno.h>
3429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartypedef int64_t nsecs_t;
3529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
3629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarenum {
3729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_SW_READ_OFTEN,
3829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_RENDERSCRIPT,
3929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_HW_TEXTURE,
4029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_HW_COMPOSER,
4129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_HW_VIDEO_ENCODER,
4229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_PROTECTED,
4329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_SW_WRITE_OFTEN,
4429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    GRALLOC_USAGE_HW_RENDER,
4529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar};
4629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
4729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#endif
4829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
4929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/** \mainpage Codec2
5029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
5129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Codec2 is a frame-based data processing API used by android.
5229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
5329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * The framework accesses components via the \ref API.
5429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
5529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
5629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/** \ingroup API
5729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
5829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * The Codec2 API defines the operation of data processing components and their interaction with
5929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * the rest of the system.
6029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
6129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Coding Conventions
6229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
6329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Mitigating Binary Compatibility.
6429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
6529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * While full binary compatibility is not a goal of the API (due to our use of STL), we try to
6629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * mitigate binary breaks by adhering to the following conventions:
6729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
6829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - at most one vtable with placeholder virtual methods
6929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all optional/placeholder virtual methods returning a status_t, with C2_NOT_IMPLEMENTED not
7029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *   requiring any update to input/output arguments.
7129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - limiting symbol export of inline methods
7229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - use of pimpl (or shared-pimpl)
7329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
7429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Naming
7529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
7629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all classes and types prefix with C2
7729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - classes for internal use prefix with _C2
7829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - enum values in global namespace prefix with C2_ all caps
7929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - enum values inside classes have no C2_ prefix as class already has it
8029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - supporting two kinds of enum naming: all-caps and kCamelCase
8129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * \todo revisit kCamelCase for param-type
8229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
8329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Aspects
8429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
8529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Aspects define certain common behavior across a group of objects.
8629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - classes whose name matches _C2.*Aspect
8729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - only protected constructors
8829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - no desctructor and copiable
8929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all methods are inline or static (this is opposite of the interface paradigm where all methods
9029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *   are virtual, which would not work due to the at most one vtable rule.)
9129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - only private variables (this prevents subclasses interfering with the aspects.)
9229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
9329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
9429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// \defgroup types Common Types
9529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @{
9629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
9729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
9829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * C2String: basic string implementation
9929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
10029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartypedef std::string C2String;
10129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartypedef const char *C2StringLiteral;
10229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
10329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
10429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * C2Error: status codes used.
10529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
10629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartypedef int32_t C2Error;
10729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarenum {
10829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#ifndef __ANDROID__
10929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    OK                  = 0,
11029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    BAD_VALUE           = -EINVAL,
11129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    BAD_INDEX           = -EOVERFLOW,
11229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    UNKNOWN_TRANSACTION = -EBADMSG,
11329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    ALREADY_EXISTS      = -EEXIST,
11429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    NAME_NOT_FOUND      = -ENOENT,
11529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    INVALID_OPERATION   = -ENOSYS,
11629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    NO_MEMORY           = -ENOMEM,
11729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    PERMISSION_DENIED   = -EPERM,
11829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    TIMED_OUT           = -ETIMEDOUT,
11929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    UNKNOWN_ERROR       = -EINVAL,
12029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#endif
12129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
12229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_OK               = OK,                   ///< operation completed successfully
12329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
12429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    // bad input
12529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_BAD_VALUE        = BAD_VALUE,            ///< argument has invalid value (user error)
12629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_BAD_INDEX        = BAD_INDEX,            ///< argument uses invalid index (user error)
12729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_UNSUPPORTED      = UNKNOWN_TRANSACTION,  ///< argument/index is value but not supported \todo is this really BAD_INDEX/VALUE?
12829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
12929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    // bad sequencing of events
13029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_DUPLICATE        = ALREADY_EXISTS,       ///< object already exists
13129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_NOT_FOUND        = NAME_NOT_FOUND,       ///< object not found
13229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_BAD_STATE        = INVALID_OPERATION,    ///< operation is not permitted in the current state
13329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
13429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    // bad environment
13529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_NO_MEMORY        = NO_MEMORY,            ///< not enough memory to complete operation
13629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_NO_PERMISSION    = PERMISSION_DENIED,    ///< missing permission to complete operation
13729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_TIMED_OUT        = TIMED_OUT,            ///< operation did not complete within timeout
13829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
13929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    // bad versioning
14029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_NOT_IMPLEMENTED  = UNKNOWN_TRANSACTION,  ///< operation is not implemented (optional only) \todo for now reuse error code
14129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
14229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    // unknown fatal
14329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    C2_CORRUPTED        = UNKNOWN_ERROR,        ///< some unexpected error prevented the operation
14429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar};
14529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
14629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @}
14729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
14829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// \defgroup utils Utilities
14929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @{
15029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
15129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_DO_NOT_COPY(type, args...) \
15229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    type args& operator=(const type args&) = delete; \
15329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    type(const type args&) = delete; \
15429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
15529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_PURE __attribute__((pure))
15629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_CONST __attribute__((const))
15729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_HIDE __attribute__((visibility("hidden")))
15829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define C2_INTERNAL __attribute__((internal_linkage))
15929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
16029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define DEFINE_OTHER_COMPARISON_OPERATORS(type) \
16129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator!=(const type &other) { return !(*this == other); } \
16229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator<=(const type &other) { return (*this == other) || (*this < other); } \
16329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator>=(const type &other) { return !(*this < other); } \
16429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator>(const type &other) { return !(*this < other) && !(*this == other); }
16529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
16629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#define DEFINE_FIELD_BASED_COMPARISON_OPERATORS(type, field) \
16729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator<(const type &other) const { return field < other.field; } \
16829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    inline bool operator==(const type &other) const { return field == other.field; } \
16929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    DEFINE_OTHER_COMPARISON_OPERATORS(type)
17029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
17129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// \cond INTERNAL
17229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
17329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// \defgroup utils_internal
17429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @{
17529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
17629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename... T> struct c2_types;
17729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
17829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/** specialization for a single type */
17929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T>
18029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarstruct c2_types<T> {
18129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename std::decay<T>::type wide_type;
18229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef wide_type narrow_type;
18329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef wide_type mintype;
18429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar};
18529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
18629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/** specialization for two types */
18729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U>
18829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarstruct c2_types<T, U> {
18929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    static_assert(std::is_floating_point<T>::value == std::is_floating_point<U>::value,
19029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar                  "mixing floating point and non-floating point types is disallowed");
19129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    static_assert(std::is_signed<T>::value == std::is_signed<U>::value,
19229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar                  "mixing signed and unsigned types is disallowed");
19329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
19429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename std::decay<
19529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar            decltype(true ? std::declval<T>() : std::declval<U>())>::type wide_type;
19629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename std::decay<
19729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar            typename std::conditional<sizeof(T) < sizeof(U), T, U>::type>::type narrow_type;
19829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename std::conditional<
19929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar            std::is_signed<T>::value, wide_type, narrow_type>::type mintype;
20029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar};
20129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
20229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @}
20329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
20429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// \endcond
20529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
20629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
20729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Type support utility class. Only supports similar classes, such as:
20829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all floating point
20929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all unsigned/all signed
21029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * - all pointer
21129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
21229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U, typename... V>
21329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarstruct c2_types<T, U, V...> {
21429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    /** Common type that accommodates all template parameter types. */
21529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<typename c2_types<T, U>::wide_type, V...>::wide_type wide_type;
21629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    /** Narrowest type of the template parameter types. */
21729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<typename c2_types<T, U>::narrow_type, V...>::narrow_type narrow_type;
21829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    /** Type that accommodates the minimum value for any input for the template parameter types. */
21929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<typename c2_types<T, U>::mintype, V...>::mintype mintype;
22029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar};
22129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
22229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
22329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *  \ingroup utils_internal
22429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * specialization for two values */
22529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U>
22629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarinline constexpr typename c2_types<T, U>::wide_type c2_max(const T a, const U b) {
22729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<T, U>::wide_type wide_type;
22829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    return ({ wide_type a_(a), b_(b); a_ > b_ ? a_ : b_; });
22929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar}
23029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
23129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
23229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Finds the maximum value of a list of "similarly typed" values.
23329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
23429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * This is an extension to std::max where the types do not have to be identical, and the smallest
23529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * resulting type is used that accommodates the argument types.
23629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
23729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
23829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * unsigned.
23929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
24029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * @return the largest of the input arguments.
24129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
24229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U, typename... V>
24329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarconstexpr typename c2_types<T, U, V...>::wide_type c2_max(const T a, const U b, const V ... c) {
24429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<T, U, V...>::wide_type wide_type;
24529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    return ({ wide_type a_(a), b_(c2_max(b, c...)); a_ > b_ ? a_ : b_; });
24629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar}
24729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
24829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
24929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *  \ingroup utils_internal
25029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * specialization for two values */
25129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U>
25229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarinline constexpr typename c2_types<T, U>::mintype c2_min(const T a, const U b) {
25329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<T, U>::wide_type wide_type;
25429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    return ({
25529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar        wide_type a_(a), b_(b);
25629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar        static_cast<typename c2_types<T, U>::mintype>(a_ < b_ ? a_ : b_);
25729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    });
25829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar}
25929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
26029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/**
26129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * Finds the minimum value of a list of "similarly typed" values.
26229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
26329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * This is an extension to std::min where the types do not have to be identical, and the smallest
26429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * resulting type is used that accommodates the argument types.
26529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
26629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
26729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * unsigned.
26829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar *
26929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar * @return the smallest of the input arguments.
27029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar */
27129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnartemplate<typename T, typename U, typename... V>
27229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnarconstexpr typename c2_types<T, U, V...>::mintype c2_min(const T a, const U b, const V ... c) {
27329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<U, V...>::mintype rest_type;
27429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    typedef typename c2_types<T, rest_type>::wide_type wide_type;
27529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    return ({
27629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar        wide_type a_(a), b_(c2_min(b, c...));
27729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar        static_cast<typename c2_types<T, rest_type>::mintype>(a_ < b_ ? a_ : b_);
27829a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar    });
27929a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar}
28029a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
28129a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar/// @}
28229a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
28329a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#ifdef __ANDROID__
28429a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar} // namespace android
28529a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#endif
28629a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar
28729a6ba9949e4127a9c6df2cc75033dbe97f501a9Lajos Molnar#endif  // C2_H_
288