1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
/************************************************************************
*
* Copyright (C) 2009-2024 IRCAD France
* Copyright (C) 2012-2019 IHU Strasbourg
*
* This file is part of Sight.
*
* Sight is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sight 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sight. If not, see <https://www.gnu.org/licenses/>.
*
***********************************************************************/
/**
* @brief This file defines fwCore base macros.
*/
#pragma once
#include "core/demangler.hpp"
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/overload.hpp>
#include <memory>
#include <string>
#include <type_traits>
#define SIGHT_NOT_USED(x) ((void) x)
/**
* @name Smart pointers macro
* @{ */
// Expand to shared_ptr < _cls_ >
#define SPTR(_cls_) std::shared_ptr<_cls_>
// Expand to shared_ptr < const _cls_ >
#define CSPTR(_cls_) std::shared_ptr<const _cls_>
// Expand to weak_ptr < _cls_ >
#define WPTR(_cls_) std::weak_ptr<_cls_>
// Expand to weak_ptr < const _cls_ >
#define CWPTR(_cls_) std::weak_ptr<const _cls_>
// Expand to unique_ptr < _cls_ >
#define UPTR(_cls_) std::unique_ptr<_cls_>
// Expand to unique_ptr < const _cls_ >
#define CUPTR(_cls_) std::unique_ptr<const _cls_>
/** @} */
/*
* @brief Define several typdefs for classes (sptr, wptr, ...)
*/
#define FWCORE_CLASS_TYPEDEFS_1(_class) \
/** Self type */ \
using self_t = _class; \
/** Type of base class */ \
using base_class_t = self_t; \
/** Type of root class */ \
using root_class_t = self_t; \
/** Shared pointer type */ \
using sptr = SPTR(self_t); \
/** Weak pointer type */ \
using wptr = WPTR(self_t); \
/** Unique pointer type */ \
using uptr = UPTR(self_t); \
/** Const shared pointer type */ \
using csptr = CSPTR(self_t); \
/** Const weak pointer type */ \
using cwptr = CWPTR(self_t); \
/** Const unique pointer type */ \
using cuptr = CUPTR(self_t); \
/**
* @brief Define several typdefs for classes (sptr, wptr, ...)
*
* base_class_t is a typedef to the superclass
*/
#define FWCORE_CLASS_TYPEDEFS_2(_class, _parent_class) \
/** Self type */ \
using self_t = _class; \
/** Type of base class */ \
using base_class_t = _parent_class; \
/** Type of root class */ \
using root_class_t = base_class_t::root_class_t; \
/** Shared pointer type */ \
using sptr = SPTR(self_t); \
/** Weak pointer type */ \
using wptr = WPTR(self_t); \
/** Unique pointer type */ \
using uptr = UPTR(self_t); \
/** Const shared pointer type */ \
using csptr = CSPTR(self_t); \
/** Const weak pointer type */ \
using cwptr = CWPTR(self_t); \
/** Const unique pointer type */ \
using cuptr = CUPTR(self_t);
#define FWCORE_STATIC_CACHE(value) \
static const std::string __cache__(value); \
return __cache__;
/**
* @brief Generate virtual methods that return classname/namespace strings
*
* Example: for data::object,
* - Classname is data::object
* - LeafClassname is Object
*/
#define FWCORE_INTERFACE_MACRO() \
/** @name Demangling methods */ \
/** @{ */ \
/** @brief return object's classname without its namespace, i.e. base_object */ \
virtual const std::string & get_leaf_classname() const \
{ \
FWCORE_STATIC_CACHE(sight::core::demangler(*this).get_leaf_classname()); \
} \
static const std::string& leaf_classname() \
{ \
FWCORE_STATIC_CACHE(sight::core::get_leaf_classname<self_t>()); \
} \
/** @brief return full object's classname with its namespace, i.e. core::base_object */ \
virtual const std::string& get_classname() const \
{ \
FWCORE_STATIC_CACHE(sight::core::get_classname<self_t>()); \
} \
static const std::string& classname() \
{ \
FWCORE_STATIC_CACHE(sight::core::get_classname<self_t>()); \
} \
/** @} */
/**
* @brief Generate virtual methods that return classname/namespace strings
*
* Example: for data::object,
* - Classname is data::object
* - LeafClassname is Object
*/
#define FWCORE_CLASSNAME_MACRO() \
/** @name Demangling methods */ \
/** @{ */ \
/** @brief return object's classname without its namespace, i.e. base_object */ \
const std::string & get_leaf_classname() const override \
{ \
FWCORE_STATIC_CACHE(sight::core::demangler(*this).get_leaf_classname()); \
} \
static const std::string& leaf_classname() \
{ \
FWCORE_STATIC_CACHE(sight::core::get_leaf_classname<self_t>()); \
} \
/** @brief return full object's classname with its namespace, i.e. core::base_object */ \
const std::string& get_classname() const override \
{ \
FWCORE_STATIC_CACHE(sight::core::get_classname<self_t>()); \
} \
static const std::string& classname() \
{ \
FWCORE_STATIC_CACHE(sight::core::get_classname<self_t>()); \
} \
/** @} */
/**
* @brief Generate virtual methods that check if passed type is same type of
* (or a topclass of) 'this' type
*
* Example:
* data::image::IsTypeOf("data::object") is true
* image->is_a("data::object") is true
*
*/
#define FWCORE_TYPE_1(_class) \
static bool is_type_of(const std::string& type) \
{ \
return self_t::classname() == type; \
} \
virtual bool is_a(const std::string& type) const \
{ \
return self_t::is_type_of(type); \
}
#define FWCORE_TYPE_2(_class, _parent_class) \
static bool is_type_of(const std::string& type) \
{ \
if(self_t::classname() == type) \
{ \
return true; \
} \
return base_class_t::is_type_of(type); \
} \
bool is_a(const std::string& type) const override \
{ \
return self_t::is_type_of(type); \
}
/**
* @brief Generate get_sptr and get_const_sptr methods
*
* These methods use 'shared_from_this' to get a shared pointer and cast it to required type
*/
#define SIGHT_ALLOW_SHARED_FROM_THIS() \
/** @brief return a casted const shared ptr from this object */ \
csptr get_const_sptr() const \
{ \
return dynamic_pointer_cast<const self_t>(this->core::base_object::shared_from_this()); \
} \
/** @brief return a casted shared ptr from this object */ \
sptr get_sptr() \
{ \
return dynamic_pointer_cast<self_t>(this->core::base_object::shared_from_this()); \
}
#if !BOOST_PP_VARIADICS_MSVC
#define SIGHT_DECLARE_CLASS(...) \
BOOST_PP_OVERLOAD(FWCORE_CLASS_MACRO_, __VA_ARGS__)(__VA_ARGS__)
#else
#define SIGHT_DECLARE_CLASS(...) \
BOOST_PP_CAT(BOOST_PP_OVERLOAD(FWCORE_CLASS_MACRO_, __VA_ARGS__)(__VA_ARGS__), BOOST_PP_EMPTY())
#endif
#define FWCORE_CLASS_MACRO_1(_class) \
FWCORE_CLASS_TYPEDEFS_1(_class) \
FWCORE_INTERFACE_MACRO() \
FWCORE_TYPE_1(_class)
#define FWCORE_CLASS_MACRO_2(_class, _parent_class) \
FWCORE_CLASS_TYPEDEFS_2(_class, _parent_class) \
FWCORE_CLASSNAME_MACRO() \
FWCORE_TYPE_2(_class, _parent_class)
#define FWCORE_CLASS_MACRO_3(_class, _parentClass, _factory) \
FWCORE_CLASS_MACRO_2(_class, _parentClass) \
static sptr make() \
{ \
return _factory(); \
}
/**
* @brief Generate common code for services classes
*/
#define SIGHT_DECLARE_SERVICE(_class, _parent_class) \
FWCORE_CLASS_MACRO_2(_class, _parent_class)
/// Force inline
#ifdef _MSC_VER
#define FINLINE __forceinline
#else
#define FINLINE __attribute__((always_inline))
#endif
namespace sight
{
template<typename T, typename deleter = std::default_delete<T> >
using uptr = std::unique_ptr<T, deleter>;
template<typename T, typename deleter = std::default_delete<T> >
using cuptr = std::unique_ptr<const T, deleter>;
template<typename T>
using sptr = std::shared_ptr<T>;
template<typename T>
using csptr = std::shared_ptr<const T>;
template<typename T>
using wptr = std::weak_ptr<T>;
template<typename T>
using cwptr = std::weak_ptr<const T>;
} // namespace sight
|