/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_
#define ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_
#ifdef __cplusplus

/* C++ version for detecting a pointer to a string. */
static inline int z_cbprintf_cxx_is_pchar(char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const char *, bool const_as_fixed)
{
	return const_as_fixed ? 0 : 1;
}

static inline int z_cbprintf_cxx_is_pchar(volatile char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const volatile char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(unsigned char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const unsigned char *, bool const_as_fixed)
{
	return const_as_fixed ? 0 : 1;
}

static inline int z_cbprintf_cxx_is_pchar(volatile unsigned char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const volatile unsigned char *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}
static inline int z_cbprintf_cxx_is_pchar(wchar_t *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const wchar_t *, bool const_as_fixed)
{
	return const_as_fixed ? 0 : 1;
}

static inline int z_cbprintf_cxx_is_pchar(volatile wchar_t *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *, bool const_as_fixed)
{
	ARG_UNUSED(const_as_fixed);
	return 1;
}

template < typename T >
static inline int z_cbprintf_cxx_is_pchar(T arg, bool const_as_fixed)
{
	ARG_UNUSED(arg);
	_Pragma("GCC diagnostic push")
	_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
	ARG_UNUSED(const_as_fixed);
	return 0;
	_Pragma("GCC diagnostic pop")
}

/* C++ version for calculating argument size. */
static inline size_t z_cbprintf_cxx_arg_size(float f)
{
	ARG_UNUSED(f);

	return sizeof(double);
}

static inline size_t z_cbprintf_cxx_arg_size(void *p)
{
	ARG_UNUSED(p);

	return sizeof(void *);
}

template < typename T >
static inline size_t z_cbprintf_cxx_arg_size(T arg)
{
	return sizeof(arg + 0);
}

/* C++ version for storing arguments. */
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, float arg)
{
	double d = (double)arg;
	void *p = &d;

	z_cbprintf_wcpy((int *)dst, (int *)p, sizeof(d) / sizeof(int));
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, void *p)
{
	z_cbprintf_wcpy((int *)dst, (int *)&p, sizeof(p) / sizeof(int));
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, char arg)
{
	int tmp = arg + 0;

	z_cbprintf_wcpy((int *)dst, &tmp, 1);
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned char arg)
{
	int tmp = arg + 0;

	z_cbprintf_wcpy((int *)dst, &tmp, 1);
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, signed char arg)
{
	int tmp = arg + 0;

	z_cbprintf_wcpy((int *)dst, &tmp, 1);
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, short arg)
{
	int tmp = arg + 0;

	z_cbprintf_wcpy((int *)dst, &tmp, 1);
}

static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned short arg)
{
	int tmp = arg + 0;

	z_cbprintf_wcpy((int *)dst, &tmp, 1);
}

template < typename T >
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, T arg)
{
	size_t wlen = z_cbprintf_cxx_arg_size(arg) / sizeof(int);
	void *p = &arg;

	z_cbprintf_wcpy((int *)dst, (int *)p, wlen);
}

/* C++ version for long double detection. */
static inline int z_cbprintf_cxx_is_longdouble(long double arg)
{
	ARG_UNUSED(arg);
	return 1;
}

template < typename T >
static inline int z_cbprintf_cxx_is_longdouble(T arg)
{
	ARG_UNUSED(arg);

	return 0;
}

/* C++ version for caluculating argument alignment. */
static inline size_t z_cbprintf_cxx_alignment(float arg)
{
	ARG_UNUSED(arg);

	return VA_STACK_ALIGN(double);
}

static inline size_t z_cbprintf_cxx_alignment(double arg)
{
	ARG_UNUSED(arg);

	return VA_STACK_ALIGN(double);
}

static inline size_t z_cbprintf_cxx_alignment(long double arg)
{
	ARG_UNUSED(arg);

	return VA_STACK_ALIGN(long double);
}

static inline size_t z_cbprintf_cxx_alignment(long long arg)
{
	ARG_UNUSED(arg);

	return VA_STACK_ALIGN(long long);
}

static inline size_t z_cbprintf_cxx_alignment(unsigned long long arg)
{
	ARG_UNUSED(arg);

	return VA_STACK_ALIGN(long long);
}

template < typename T >
static inline size_t z_cbprintf_cxx_alignment(T arg)
{
	return MAX(__alignof__(arg), VA_STACK_MIN_ALIGN);
}

/* C++ version for checking if two arguments are same type */
template < typename T1, typename T2 >
struct z_cbprintf_cxx_is_same_type {
	enum {
		value = false
	};
};

template < typename T >
struct z_cbprintf_cxx_is_same_type < T, T > {
	enum {
		value = true
	};
};

template < typename T >
struct z_cbprintf_cxx_remove_reference {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_reference < T & > {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_reference < T && > {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_cv {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_cv < const T > {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_cv < volatile T > {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_cv < const volatile T > {
	typedef T type;
};

/* Determine if a type is an array */
template < typename T >
struct z_cbprintf_cxx_is_array {
	enum {
		value = false
	};
};

template < typename T >
struct z_cbprintf_cxx_is_array < T[] > {
	enum {
		value = true
	};
};

template < typename T, size_t N >
struct z_cbprintf_cxx_is_array < T[N] > {
	enum {
		value = true
	};
};

/* Determine the type of elements in an array */
template < typename T >
struct z_cbprintf_cxx_remove_extent {
	typedef T type;
};

template < typename T >
struct z_cbprintf_cxx_remove_extent < T[] > {
	typedef T type;
};

template < typename T, size_t N >
struct z_cbprintf_cxx_remove_extent < T[N] > {
	typedef T type;
};

#endif /* __cplusplus */
#endif /* ZEPHYR_INCLUDE_SYS_CBPRINTF_CXX_H_ */
