/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/14///15/// @file AP_Common.h16/// @brief Common definitions and utility routines for the ArduPilot17/// libraries.18///1920#pragma once2122#include <stdint.h>23#include <stdlib.h>24#include <type_traits>25#include <new>2627// used to pack structures28#define PACKED __attribute__((__packed__))2930#if !defined(CYGWIN_BUILD)31// used to weaken symbols32#define WEAK __attribute__((__weak__))33#else34// cygwin cannot properly support weak symbols allegedly due to Windows35// executable format limitations36// (see https://www.cygwin.com/faq.html#faq.programming.linker ). fortunately37// we only use weak symbols for tests and some HAL stuff which SITL and38// therefore cygwin does not need to override. in the event that overriding is39// attempted the link will fail with a symbol redefinition error hopefully40// suggesting that an alternate approach is needed.41#define WEAK42#endif4344// used to mark a function that may be unused in some builds45#define UNUSED_FUNCTION __attribute__((unused))4647// used to mark an attribute that may be unused in some builds48#ifdef __clang__49#define UNUSED_PRIVATE_MEMBER __attribute__((unused))50#else51#define UNUSED_PRIVATE_MEMBER52#endif5354// this can be used to optimize individual functions55#define OPTIMIZE(level) __attribute__((optimize(level)))5657// sometimes we need to prevent inlining to prevent large stack usage58#ifndef NOINLINE59#define NOINLINE __attribute__((noinline))60#endif6162// used to ignore results for functions marked as warn unused63#define IGNORE_RETURN(x) do {if (x) {}} while(0)6465#define FMT_PRINTF(a,b) __attribute__((format(printf, a, b)))66#define FMT_SCANF(a,b) __attribute__((format(scanf, a, b)))6768// used to forbid copy of objects69#define CLASS_NO_COPY(c) c(const c &other) = delete; c &operator=(const c&) = delete7071#ifdef __has_cpp_attribute72# if __has_cpp_attribute(fallthrough)73# define FALLTHROUGH [[fallthrough]]74# elif __has_cpp_attribute(gnu::fallthrough)75# define FALLTHROUGH [[gnu::fallthrough]]76# endif77#endif78#ifndef FALLTHROUGH79# define FALLTHROUGH80#endif8182#ifdef __GNUC__83#define WARN_IF_UNUSED __attribute__ ((warn_unused_result))84#else85#define WARN_IF_UNUSED86#endif8788#define NORETURN __attribute__ ((noreturn))8990/* Declare and implement const and non-const versions of the array subscript91* operator. The object is treated as an array of type_ values. */92#define DEFINE_BYTE_ARRAY_METHODS \93inline uint8_t &operator[](size_t i) { return reinterpret_cast<uint8_t *>(this)[i]; } \94inline uint8_t operator[](size_t i) const { return reinterpret_cast<const uint8_t *>(this)[i]; }9596/*97check if bit bitnumber is set in value, returned as a98bool. Bitnumber starts at 0 for the first bit99*/100#define BIT_IS_SET(value, bitnumber) (((value) & (1U<<(bitnumber))) != 0)101#define BIT_IS_SET_64(value, bitnumber) (((value) & (uint64_t(1U)<<(bitnumber))) != 0)102103// get high or low bytes from 2 byte integer104#define LOWBYTE(i) ((uint8_t)(i))105#define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8))106107#define ARRAY_SIZE(_arr) (sizeof(_arr) / sizeof(_arr[0]))108109#define UINT16_VALUE(hbyte, lbyte) (static_cast<uint16_t>(((hbyte)<<8)|(lbyte)))110#define UINT32_VALUE(b3, b2, b1, b0) (static_cast<uint32_t>(((b3)<<24)|((b2)<<16)|((b1)<<8)|(b0)))111112/*113* See UNUSED_RESULT. The difference is that it receives @uniq_ as the name to114* be used for its internal variable.115*116* @uniq_: a unique name to use for variable name117* @expr_: the expression to be evaluated118*/119#define _UNUSED_RESULT(uniq_, expr_) \120do { \121decltype(expr_) uniq_ __attribute__((unused)); \122uniq_ = expr_; \123} while (0)124125/*126* Allow to call a function annotated with warn_unused_result attribute127* without getting a warning, because sometimes this is what we want to do.128*129* @expr_: the expression to be evaluated130*/131#define UNUSED_RESULT(expr_) _UNUSED_RESULT(__unique_name_##__COUNTER__, expr_)132133// @}134135// STR_VALUE returns the string equivalent for the passed cpp macro, so e.g.136// printf("%s", STR_VALUE(EINVAL)); will print "EINVAL"137#define STR_VALUE(x) #x138139// assert_storage_size template: assert that the memory used to store an140// item is of a specific size.141// example invocation:142// assert_storage_size<class Location, 16> _assert_storage_size_Location;143// templates are used for this because the compiler's output will144// usually contain details of the template instantiation so you can145// see how the actual size differs from the expected size.146template<typename s, size_t s_size, size_t t> struct _assert_storage_size {147static_assert(s_size == t, "wrong size");148};149template<typename s, size_t t> struct assert_storage_size {150_assert_storage_size<s, sizeof(s), t> _member;151};152153#define ASSERT_STORAGE_SIZE_JOIN( name, line ) ASSERT_STORAGE_SIZE_DO_JOIN( name, line )154#define ASSERT_STORAGE_SIZE_DO_JOIN( name, line ) name ## line155#define ASSERT_STORAGE_SIZE(structure, size) \156do { assert_storage_size<structure, size> ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); (void)ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); } while(false)157158////////////////////////////////////////////////////////////////////////////////159/// @name Conversions160///161/// Conversion macros and factors.162///163//@{164165/*166Return true if value is between lower and upper bound inclusive.167False otherwise.168*/169bool is_bounded_int32(int32_t value, int32_t lower_bound, int32_t upper_bound);170171bool hex_to_uint8(uint8_t a, uint8_t &res); // return the uint8 value of an ascii hex character172173/*174strncpy without the warning for not leaving room for nul termination175*/176size_t strncpy_noterm(char *dest, const char *src, size_t n);177178// return the numeric value of an ascii hex character179uint8_t char_to_hex(char a);180181/*182Bit manipulation183*/184//#define BIT_SET(value, bitnumber) ((value) |= (((typeof(value))1U) << (bitnumber)))185template <typename T> void BIT_SET (T& value, uint8_t bitnumber) noexcept {186static_assert(std::is_integral<T>::value, "Integral required.");187((value) |= ((T)(1U) << (bitnumber)));188}189//#define BIT_CLEAR(value, bitnumber) ((value) &= ~(((typeof(value))1U) << (bitnumber)))190template <typename T> void BIT_CLEAR (T& value, uint8_t bitnumber) noexcept {191static_assert(std::is_integral<T>::value, "Integral required.");192((value) &= ~((T)(1U) << (bitnumber)));193}194195/*196See the comments in libraries/AP_Common/c++.cpp197*/198#ifndef NEW_NOTHROW199#define NEW_NOTHROW new(std::nothrow)200#endif201202void * WEAK mem_realloc(void *ptr, size_t old_size, size_t new_size);203204205