From 390a22f864537eb09efb8341c4f5917e6418a9c8 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 8 Sep 2016 18:38:53 +0100 Subject: [PATCH 1/4] Enable FINAL, (un)linkely, __attribute__ for clang. --- src/stdafx.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/stdafx.h b/src/stdafx.h index 631f64cca7..e19d015ed9 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -143,7 +143,7 @@ #endif /* PSP */ /* Stuff for GCC */ -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) #define NORETURN __attribute__ ((noreturn)) #define CDECL #define __int64 long long @@ -151,12 +151,8 @@ /* Warn about functions using 'printf' format syntax. First argument determines which parameter * is the format string, second argument is start of values passed to printf. */ #define WARN_FORMAT(string, args) __attribute__ ((format (printf, string, args))) - #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) - #define FINAL final - #else - #define FINAL - #endif -#endif /* __GNUC__ */ + #define FINAL final +#endif /* __GNUC__ || __clang__ */ #if defined(__WATCOMC__) #define NORETURN @@ -431,13 +427,13 @@ assert_compile(SIZE_MAX >= UINT32_MAX); #define CloseConnection OTTD_CloseConnection #endif /* __APPLE__ */ -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__clang__) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else #define likely(x) (x) #define unlikely(x) (x) -#endif +#endif /* __GNUC__ || __clang__ */ void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2); void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2); From 8a2f9311a9d1e5652475568b75f9a91082c127bd Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 8 Sep 2016 19:31:40 +0100 Subject: [PATCH 2/4] Include -01 in CFLAGS_BUILD when using clang. --- config.lib | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.lib b/config.lib index 961e5eae8c..ae9b5be2c1 100644 --- a/config.lib +++ b/config.lib @@ -1524,8 +1524,11 @@ make_cflags_and_ldflags() { cc_build_is_gcc=`basename "$cc_build" | grep "gcc" 2>/dev/null` if [ -n "$cc_build_is_gcc" ]; then - # Just add -O1 to the tools needed for building. + # Add -O1 and fortify source to the tools needed for building, on gcc CFLAGS_BUILD="$CFLAGS_BUILD -D_FORTIFY_SOURCE=2 -O1" + elif [ -n "`basename "$cc_build" | grep "clang" 2>/dev/null`" ]; then + # Add -O1 to the tools needed for building, on clang + CFLAGS_BUILD="$CFLAGS_BUILD -O1" fi fi From ea2b04a6be83cbc8714cf6fb9698a2346c1f6325 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 9 Sep 2016 21:10:39 +0100 Subject: [PATCH 3/4] Add C++11 container utility functions. --- source.list | 1 + src/core/container_func.hpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/core/container_func.hpp diff --git a/source.list b/source.list index 59b2824ad0..b2c2f4d495 100644 --- a/source.list +++ b/source.list @@ -423,6 +423,7 @@ core/alloc_type.hpp core/backup_type.hpp core/bitmath_func.cpp core/bitmath_func.hpp +core/container_func.hpp core/endian_func.hpp core/endian_type.hpp core/enum_type.hpp diff --git a/src/core/container_func.hpp b/src/core/container_func.hpp new file mode 100644 index 0000000000..1b8e8ad847 --- /dev/null +++ b/src/core/container_func.hpp @@ -0,0 +1,35 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file container_func.hpp Functions related to use of containers. */ + +template unsigned int container_unordered_remove_if (C &container, UP predicate) { + unsigned int removecount = 0; + for (auto it = container.begin(); it != container.end();) { + if (predicate(*it)) { + removecount++; + if (std::next(it) != container.end()) { + *it = std::move(container.back()); + container.pop_back(); + } else { + container.pop_back(); + break; + } + } else { + ++it; + } + } + return removecount; +} + +template unsigned int container_unordered_remove(C &container, const V &value) { + return container_unordered_remove_if (container, [&](const typename C::value_type &v) { + return v == value; + }); +} From 13fb737bed0b94dc031db433bce04702b0d658a4 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 12 Sep 2016 22:48:58 +0100 Subject: [PATCH 4/4] Add a template parameter for the inner container of MultiMap. --- src/core/multimap.hpp | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/core/multimap.hpp b/src/core/multimap.hpp index e906677141..da6a33ef45 100644 --- a/src/core/multimap.hpp +++ b/src/core/multimap.hpp @@ -15,7 +15,7 @@ #include #include -template +template class MultiMap; /** @@ -23,14 +23,15 @@ class MultiMap; * @tparam Tmap_iter Iterator type for the map in the MultiMap. * @tparam Tlist_iter Iterator type for the lists in the MultiMap. * @tparam Tkey Key type of the MultiMap. - * @tparam Tvalue Value type of the MultMap. + * @tparam Tvalue Value type of the MultiMap. + * @tparam Tcontainer Container type for the values of the MultiMap. * @tparam Tcompare Comparator type for keys of the MultiMap. */ -template +template class MultiMapIterator { protected: - friend class MultiMap; - typedef MultiMapIterator Self; + friend class MultiMap; + typedef MultiMapIterator Self; Tlist_iter list_iter; ///< Iterator pointing to current position in the current list of items with equal keys. Tmap_iter map_iter; ///< Iterator pointing to the position of the current list of items with equal keys in the map. @@ -201,8 +202,8 @@ public: * @param iter2 Second iterator to compare. * @return If iter1 and iter2 are equal. */ -template -bool operator==(const MultiMapIterator &iter1, const MultiMapIterator &iter2) +template +bool operator==(const MultiMapIterator &iter1, const MultiMapIterator &iter2) { if (iter1.GetMapIter() != iter2.GetMapIter()) return false; if (!iter1.ListValid()) return !iter2.ListValid(); @@ -218,8 +219,8 @@ bool operator==(const MultiMapIterator -bool operator!=(const MultiMapIterator &iter1, const MultiMapIterator &iter2) +template +bool operator!=(const MultiMapIterator &iter1, const MultiMapIterator &iter2) { return !(iter1 == iter2); } @@ -232,8 +233,8 @@ bool operator!=(const MultiMapIterator -bool operator==(const MultiMapIterator &iter1, const Tmap_iter2 &iter2) +template +bool operator==(const MultiMapIterator &iter1, const Tmap_iter2 &iter2) { return !iter1.ListValid() && iter1.GetMapIter() == iter2; } @@ -244,8 +245,8 @@ bool operator==(const MultiMapIterator -bool operator!=(const MultiMapIterator &iter1, const Tmap_iter2 &iter2) +template +bool operator!=(const MultiMapIterator &iter1, const Tmap_iter2 &iter2) { return iter1.ListValid() || iter1.GetMapIter() != iter2; } @@ -256,8 +257,8 @@ bool operator!=(const MultiMapIterator -bool operator==(const Tmap_iter2 &iter2, const MultiMapIterator &iter1) +template +bool operator==(const Tmap_iter2 &iter2, const MultiMapIterator &iter1) { return !iter1.ListValid() && iter1.GetMapIter() == iter2; } @@ -268,8 +269,8 @@ bool operator==(const Tmap_iter2 &iter2, const MultiMapIterator -bool operator!=(const Tmap_iter2 &iter2, const MultiMapIterator &iter1) +template +bool operator!=(const Tmap_iter2 &iter2, const MultiMapIterator &iter1) { return iter1.ListValid() || iter1.GetMapIter() != iter2; } @@ -282,10 +283,10 @@ bool operator!=(const Tmap_iter2 &iter2, const MultiMapIterator > -class MultiMap : public std::map, Tcompare > { +template, typename Tcompare = std::less > +class MultiMap : public std::map { public: - typedef typename std::list List; + typedef Tcontainer List; typedef typename List::iterator ListIterator; typedef typename List::const_iterator ConstListIterator; @@ -293,8 +294,8 @@ public: typedef typename Map::iterator MapIterator; typedef typename Map::const_iterator ConstMapIterator; - typedef MultiMapIterator iterator; - typedef MultiMapIterator const_iterator; + typedef MultiMapIterator iterator; + typedef MultiMapIterator const_iterator; /** * Erase the value pointed to by an iterator. The iterator may be invalid afterwards.