/* **************************************************************************** * Copyright 2019 Open Systems Development BV * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * ***************************************************************************/ #ifndef OSDEV_COMPONENTS_MQTT_UTILS_H #define OSDEV_COMPONENTS_MQTT_UTILS_H // std #include #include #include #include namespace osdev { namespace components { namespace mqtt { /** * @brief Does nothing. * Utility template function to explicitly use parameters, that would otherwise be unused. * This helps to prevent the -Wunused-parameter warning. */ template void apply_unused_parameters(const Args&...) { } /** * @brief Converts (dynamic_cast) a std::unique_ptr from TFrom to TTo. * @param from The std::unique_ptr to convert from TFrom to TTo. * @return The converted std::unique_ptr. */ template std::unique_ptr dynamic_unique_ptr_cast(std::unique_ptr&& from) { auto to = dynamic_cast(from.get()); if (nullptr == to) { return std::unique_ptr(nullptr); } from.release(); return std::unique_ptr(to); } /** * @brief Converts (dynamic_cast) a std::unique_ptr from TFrom to TTo. * @param from The std::unique_ptr to convert from TFrom to TTo. * @return The converted std::unique_ptr. */ template std::unique_ptr dynamic_unique_ptr_cast(std::unique_ptr&& from) { auto to = dynamic_cast(from.get()); if (nullptr == to) { return std::unique_ptr(nullptr, from.get_deleter()); } from.release(); return std::unique_ptr(to, std::move(from.get_deleter())); } /** * @brief Helper class for iteration of keys of a map. */ template class KeyIterator : public TMap::iterator { public: typedef typename TMap::iterator MapIterator; typedef typename MapIterator::value_type::first_type KeyType; KeyIterator(const MapIterator& other) : TMap::iterator(other) { } KeyType& operator*() { return TMap::iterator::operator*().first; } }; /** * @brief Helper function to get the begin KeyIterator from a map. */ template KeyIterator KeyBegin(MapType& map) { return KeyIterator(map.begin()); } /** * @brief Helper function to get the end KeyIterator from a map. */ template KeyIterator KeyEnd(MapType& map) { return KeyIterator(map.end()); } /** * @brief Helper class for iteration of keys of a const map. */ template class KeyConstIterator : public TMap::const_iterator { typedef typename TMap::const_iterator TMapIterator; typedef typename TMapIterator::value_type::first_type TKeyType; public: KeyConstIterator(const TMapIterator& other) : TMapIterator(other) { } const TKeyType& operator*() { return TMapIterator::operator*().first; } }; /** * @brief Helper function to get the cbegin KeyConstIterator from a const map. */ template KeyConstIterator KeyBegin(const TMap& map) { return KeyConstIterator(map.cbegin()); } /** * @brief Helper function to get the cend KeyConstIterator from a const map. */ template KeyConstIterator KeyEnd(const TMap& map) { return KeyConstIterator(map.cend()); } /** * @brief Helper function to get the difference of the keys in two maps. * @param map1 The first map for which to examine the keys. * @param map2 The second map for which to examine the keys. * @return Collection of keys present in map1, but not in map2. * @note The types of the keys in the maps must be identical. */ template std::vector keyDifference( const TMap1& map1, const TMap2& map2, const std::function& keyCompare = std::less()) { static_assert(std::is_same< typename TMap1::key_type, typename TMap2::key_type>::value, "Inconsistent key types."); typedef typename TMap1::key_type Key; std::vector onlyInMap1; std::set_difference( KeyBegin(map1), KeyEnd(map1), KeyBegin(map2), KeyEnd(map2), std::inserter(onlyInMap1, onlyInMap1.begin()), keyCompare); return onlyInMap1; } /** * @brief Helper function to get the intersection of the keys in two maps. * @param map1 The first map for which to examine the keys. * @param map2 The second map for which to examine the keys. * @return Collection of keys present in both maps. * @note The types of the keys in the maps must be identical. */ template std::vector keyIntersection( const TMap1& map1, const TMap2& map2, const std::function& keyCompare = std::less()) { static_assert(std::is_same< typename TMap1::key_type, typename TMap2::key_type>::value, "Inconsistent key types."); typedef typename TMap1::key_type Key; std::vector inBothMaps; std::set_intersection( KeyBegin(map1), KeyEnd(map1), KeyBegin(map2), KeyEnd(map2), std::inserter(inBothMaps, inBothMaps.begin()), keyCompare); return inBothMaps; } /** * @brief Determine the absolute path of the binary that belongs to a process. * @param pid Process Id ifor which to determine the path to the binary. If pid equals -1 then the pid of the current process is used. * @return Absolute path to the binary. * @throw SystemException if call to readlink fails. * @throw PathException if path is to long. * @note Works only for processes owned by the user that is calling this function. */ std::string getPathToBinary(int pid = -1); } // End namespace mqtt } // End namespace components } // End namespace osdev #endif // OSDEV_COMPONENTS_MQTT_UTILS_H