diff options
author | Bjoern Michaelsen <bjoern.michaelsen@libreoffice.org> | 2021-01-09 21:49:51 +0100 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@libreoffice.org> | 2021-01-13 18:20:09 +0100 |
commit | fcb6e076d9004ef907a2616d04bf9c39908e6e8a (patch) | |
tree | 28f691da69e537efb1162bec2d1183ddc82154e8 /include/svl | |
parent | 6ce3e7b615193f610add5428d2157f31600dec52 (diff) |
SfxPoolItem: introduce StaticWhichCast and DynamicWhichCast
- at least in Writer it is a common pattern to switch case on a Which
and then static_cast the SfxPoolItem to the assumed "right" type
- instead, it would much less errorprone to use the TypedWhichId to be
sure to cast to the right, matching type for an id
- also, this allow to assert the dynamic_cast in debug build to
highlight type confusion
- finally, there is some example use added in sw showing how it gets rid
of explicit manual lookup of the type to cast to
- likely, many of the static_cast<TypedWhichId>(SfxPoolItem*) can be
found and replaced with a compiler plugin. This is left as an exercise
to the reader.
- alternatively, this might be a nice easy EasyHack to start ....
Change-Id: I00110c0fe25626bc89d835e3c4e7ff75839756b0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109042
Tested-by: Jenkins
Reviewed-by: Bjoern Michaelsen <bjoern.michaelsen@libreoffice.org>
Diffstat (limited to 'include/svl')
-rw-r--r-- | include/svl/poolitem.hxx | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index ce4ebeaef679..8ccf65e5565c 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -149,6 +149,39 @@ public: m_nWhich = nId; } sal_uInt16 Which() const { return m_nWhich; } + // StaticWhichCast asserts if the TypedWhichId is not matching its type, otherwise it returns a reference. + // You can use StaticWhichCast when you are sure about the type at compile time -- like a static_cast. + template<class T> T& StaticWhichCast(TypedWhichId<T> nId) + { + (void)nId; + assert(nId == m_nWhich); + assert(dynamic_cast<T*>(this)); + return *static_cast<T*>(this); + } + template<class T> const T& StaticWhichCast(TypedWhichId<T> nId) const + { + (void)nId; + assert(nId == m_nWhich); + assert(dynamic_cast<const T*>(this)); + return *static_cast<const T*>(this); + } + // DynamicWhichCast returns nullptr if the TypedWhichId is not matching its type, otherwise it returns a typed pointer. + // it asserts if the TypedWhichId matches its Which, but not the RTTI type. + // You can use DynamicWhichCast when you are not sure about the type at compile time -- like a dynamic_cast. + template<class T> T* DynamicWhichCast(TypedWhichId<T> nId) + { + if(m_nWhich != nId) + return nullptr; + assert(dynamic_cast<T*>(this)); + return static_cast<T*>(this); + } + template<class T> const T* DynamicWhichCast(TypedWhichId<T> nId) const + { + if(m_nWhich != nId) + return nullptr; + assert(dynamic_cast<const T*>(this)); + return static_cast<const T*>(this); + } virtual bool operator==( const SfxPoolItem& ) const = 0; bool operator!=( const SfxPoolItem& rItem ) const { return !(*this == rItem); } |