blob: 991929fac7de644ca1c05b0063c9c093a969bd0f [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_MACROS_H_
#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_MACROS_H_
#include <string>
#include "base/macros/concat.h"
namespace apps {
#define SET_OPTIONAL_VALUE(VALUE) \
if (delta->VALUE.has_value()) { \
state->VALUE = delta->VALUE; \
}
#define SET_ENUM_VALUE(VALUE, DEFAULT_VALUE) \
if (delta->VALUE != DEFAULT_VALUE) { \
state->VALUE = delta->VALUE; \
}
#define GET_VALUE(VALUE) \
if (delta_ && delta_->VALUE()) { \
return delta_->VALUE(); \
} \
if (state_ && state_->VALUE()) { \
return state_->VALUE(); \
} \
return nullptr;
#define IS_VALUE_CHANGED(VALUE) \
return delta_ && delta_->VALUE() && \
(!state_ || (delta_->VALUE() != state_->VALUE()));
#define GET_VALUE_WITH_FALLBACK(VALUE, FALLBACK_VALUE) \
if (delta_ && delta_->VALUE.has_value()) { \
return delta_->VALUE.value(); \
} \
if (state_ && state_->VALUE.has_value()) { \
return state_->VALUE.value(); \
} \
return FALLBACK_VALUE;
#define GET_VALUE_WITH_DEFAULT_VALUE(VALUE, DEFAULT_VALUE) \
if (delta_ && delta_->VALUE != (DEFAULT_VALUE)) { \
return delta_->VALUE; \
} \
if (state_) { \
return state_->VALUE; \
} \
return DEFAULT_VALUE;
#define IS_VALUE_CHANGED_WITH_DEFAULT_VALUE(VALUE, DEFAULT_VALUE) \
return delta_ && (delta_->VALUE != DEFAULT_VALUE) && \
(!state_ || (delta_->VALUE != state_->VALUE));
#define GET_VALUE_WITH_CHECK_AND_DEFAULT_RETURN(VALUE, CHECK, DEFAULT_RETURN) \
if (delta_ && !delta_->VALUE.CHECK()) { \
return delta_->VALUE; \
} \
if (state_ && !state_->VALUE.CHECK()) { \
return state_->VALUE; \
} \
return DEFAULT_RETURN;
#define IS_VALUE_CHANGED_WITH_CHECK(VALUE, CHECK) \
return delta_ && !delta_->VALUE.CHECK() && \
(!state_ || (delta_->VALUE != state_->VALUE));
#define RETURN_OPTIONAL_VALUE_CHANGED(VALUE) \
return delta_ && delta_->VALUE.has_value() && \
(!state_ || (delta_->VALUE != state_->VALUE));
#define PRINT_OPTIONAL_BOOL(VALUE) \
(VALUE.has_value() ? (VALUE.value() ? "true" : "false") : "null")
#define IS_VECTOR_VALUE_EQUAL(VALUE) \
if (this->VALUE.size() != other.VALUE.size()) { \
return false; \
} \
for (size_t i = 0; i < other.VALUE.size(); i++) { \
if (this->VALUE[i] != other.VALUE[i]) { \
return false; \
} \
}
// Macros for enum
#define ARC_COUNT_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
_14, _15, _16, N, ...) \
N
#define ARG_COUNT(...) \
ARC_COUNT_(0, ##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, \
3, 2, 1, 0)
// Go through all items in enum to generate code for each element.
#define DOARG1(FUNC, CLASSNAME, ELEM) FUNC(CLASSNAME, ELEM)
#define DOARG2(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG1(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG3(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG2(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG4(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG3(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG5(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG4(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG6(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG5(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG7(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG6(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG8(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG7(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG9(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG8(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG10(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG9(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG11(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG10(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG12(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG11(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG13(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG12(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG14(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG13(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG15(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG14(FUNC, CLASSNAME, __VA_ARGS__)
#define DOARG16(FUNC, CLASSNAME, ELEM1, ...) \
DOARG1(FUNC, CLASSNAME, ELEM1) DOARG15(FUNC, CLASSNAME, __VA_ARGS__)
#define FOREACH_(FUNC, CLASSNAME, ...) \
BASE_CONCAT(DOARG, ARG_COUNT(__VA_ARGS__))(FUNC, CLASSNAME, __VA_ARGS__)
#define GET_ELEM(N, ...) BASE_CONCAT(GET_ELEM, N)(__VA_ARGS__)
#define GET_ELEM1(_1, ...) _1
#define GET_ELEM2(_1, _2, ...) _2
#define GET_ELEM3(_1, _2, _3, ...) _3
#define GET_ELEM4(_1, _2, _3, _4, ...) _4
#define GET_ELEM5(_1, _2, _3, _4, _5, ...) _5
#define GET_ELEM6(_1, _2, _3, _4, _5, _6, ...) _6
#define GET_ELEM7(_1, _2, _3, _4, _5, _6, _7, ...) _7
#define GET_ELEM8(_1, _2, _3, _4, _5, _6, _7, _8, ...) _8
#define GET_ELEM9(_1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9
#define GET_ELEM10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) _10
#define GET_ELEM11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) _11
#define GET_ELEM12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) _12
#define GET_ELEM13(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
...) \
_13
#define GET_ELEM14(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
_14, ...) \
_14
#define GET_ELEM15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
_14, _15, ...) \
_15
#define GET_ELEM16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
_14, _15, _16, ...) \
_16
// Get last argument.
#define GET_LAST(...) GET_ELEM(ARG_COUNT(__VA_ARGS__), __VA_ARGS__),
// Macros for enum definitions
#define ELEM(CLASSNAME, E) E,
// Macro to generate enum `CLASSNAME` for elements, and the definition for the
// `EnumToString`, e.g.:
// enum class ClassName {
// kUnknown,
// kElement1,
// kElement2,
// kElement3,
// kMaxValue = kElement3,
// };
// COMPONENT_EXPORT(APP_TYPES)
// std::string EnumToString(ClassName input);
//
// Modify ARC_COUNT, GET_ELEMXX and DOARGXX to support more elements.
#define ENUM(CLASSNAME, ...) \
enum class CLASSNAME { \
FOREACH_(ELEM, CLASSNAME, __VA_ARGS__) kMaxValue = GET_LAST(__VA_ARGS__) \
}; \
COMPONENT_EXPORT(APP_TYPES) \
std::string EnumToString(CLASSNAME input);
#define ENUM_FOR_COMPONENT(COMPONENT, CLASSNAME, ...) \
enum class CLASSNAME { FOREACH_(ELEM, CLASSNAME, __VA_ARGS__) }; \
COMPONENT_EXPORT(COMPONENT) \
std::string EnumToString(CLASSNAME input);
// Macros to print enum
#define PRINT_CLASSNAME_AND_ELEM(CLASSNAME, ELEM) \
std::string(#CLASSNAME) + std::string("::") + std::string(#ELEM)
#define PRINT_ELEM(CLASSNAME, ELEM) \
case CLASSNAME::ELEM: \
return PRINT_CLASSNAME_AND_ELEM(CLASSNAME, ELEM);
// Macro to generate the function `EnumToString` to print the enum `CLASSNAME`
// elements, e.g.:
// std::string EnumToString(ClassName input) {
// switch (input) {
// case ClassName::kElement1:
// return "ClassName::kElement1";
// case ClassName::kElement2:
// return "ClassName::kElement2";
// case ClassName::kElement3:
// return "ClassName::kElement1";
// }
// }
//
// Modify ARC_COUNT, GET_ELEMXX and DOARGXX to support more elements.
#define APP_ENUM_TO_STRING(CLASSNAME, ...) \
std::string EnumToString(CLASSNAME input) { \
switch (input) { FOREACH_(PRINT_ELEM, CLASSNAME, __VA_ARGS__) } \
}
} // namespace apps
#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_MACROS_H_