/* Copyright (C) 2019 * * This file is part of the osdev components suite * * 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 2, 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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