From 613a6ff76307053f5dda4bb14c4474caad1a9b6f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 2 Oct 2017 10:14:43 +0200 Subject: [PATCH] feat(core): add a private-access file to access private data --- include/linphone/utils/private-access.h | 60 +++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 include/linphone/utils/private-access.h diff --git a/include/linphone/utils/private-access.h b/include/linphone/utils/private-access.h new file mode 100644 index 000000000..776fd8043 --- /dev/null +++ b/include/linphone/utils/private-access.h @@ -0,0 +1,60 @@ +/* + * private-access.h + * Copyright (C) 2017 Belledonne Communications SARL + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// ============================================================================= +// Tools to get/set private data of Cpp objects. +// +// See: https://bloglitb.blogspot.fr/2011/12/access-to-private-members-safer.html +// See: http://en.cppreference.com/w/cpp/language/adl +// See: http://en.cppreference.com/w/cpp/language/friend +// ============================================================================= + +#ifndef _PRIVATE_ACCESS_H_ +#define _PRIVATE_ACCESS_H_ + +#include + +#define L_INTERNAL_STRUCT_L_ATTR_GET(CLASS, ATTR_NAME) AttrGet ## _ ## CLASS ## _ ## ATTR_NAME +#define L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) AttrSpy ## _ ## ATTR_NAME + +#define L_ENABLE_ATTR_ACCESS(CLASS, ATTR_TYPE, ATTR_NAME) \ + template \ + struct L_INTERNAL_STRUCT_L_ATTR_GET(CLASS, ATTR_NAME) { \ + friend constexpr ATTR_TYPE (CLASS::*get(AttrSpy *)) { \ + return Attr; \ + } \ + }; \ + template \ + struct L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME); \ + template<> \ + struct L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) { \ + friend constexpr ATTR_TYPE (CLASS::*get(L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) *)); \ + }; \ + template struct L_INTERNAL_STRUCT_L_ATTR_GET(CLASS, ATTR_NAME)< \ + L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME), \ + &CLASS::ATTR_NAME \ + >; + +// Warning: Allow to modify const data. +// Returns a ref to `ATTR_NAME`. +#define L_ATTR_GET(OBJECT, ATTR_NAME) \ + (const_cast::type &>(OBJECT)).*get( \ + static_cast::type> *>(nullptr) \ + ) + +#endif // ifndef _PRIVATE_ACCESS_H_