From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/llcommon/llstl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llstl.h') diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 25131291f9..e39769fe9d 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -532,7 +532,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs) return strcmp(lhs->name(), rhs->name()) < 0; #else // not Linux, or gcc 4.4+ // Just use before(), as we normally would - return lhs->before(*rhs) ? true : false; + return lhs->before(*rhs); #endif } -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/llcommon/llstl.h | 1426 ++++++++++++++++++++++++------------------------ 1 file changed, 713 insertions(+), 713 deletions(-) (limited to 'indra/llcommon/llstl.h') diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index f2d268bb9a..67b4c141af 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -1,713 +1,713 @@ -/** - * @file llstl.h - * @brief helper object & functions for use with the stl. - * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library 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; - * version 2.1 of the License only. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLSTL_H -#define LL_LLSTL_H - -#include "stdtypes.h" -#include -#include -#include -#include -#include -#include -#include - -#ifdef LL_LINUX -// For strcmp -#include -#endif -// Use to compare the first element only of a pair -// e.g. typedef std::set, compare_pair > some_pair_set_t; -template -struct compare_pair_first -{ - bool operator()(const std::pair& a, const std::pair& b) const - { - return a.first < b.first; - } -}; - -template -struct compare_pair_greater -{ - bool operator()(const std::pair& a, const std::pair& b) const - { - if (!(a.first < b.first)) - return true; - else if (!(b.first < a.first)) - return false; - else - return !(a.second < b.second); - } -}; - -// Use to compare the contents of two pointers (e.g. std::string*) -template -struct compare_pointer_contents -{ - typedef const T* Tptr; - bool operator()(const Tptr& a, const Tptr& b) const - { - return *a < *b; - } -}; - -// DeletePointer is a simple helper for deleting all pointers in a container. -// The general form is: -// -// std::for_each(cont.begin(), cont.end(), DeletePointer()); -// somemap.clear(); -// -// Don't forget to clear()! - -struct DeletePointer -{ - template void operator()(T* ptr) const - { - delete ptr; - } -}; -struct DeletePointerArray -{ - template void operator()(T* ptr) const - { - delete[] ptr; - } -}; - -// DeletePairedPointer is a simple helper for deleting all pointers in a map. -// The general form is: -// -// std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer()); -// somemap.clear(); // Don't leave dangling pointers around - -struct DeletePairedPointer -{ - template void operator()(T &ptr) const - { - delete ptr.second; - ptr.second = NULL; - } -}; -struct DeletePairedPointerArray -{ - template void operator()(T &ptr) const - { - delete[] ptr.second; - ptr.second = NULL; - } -}; - - -// Alternate version of the above so that has a more cumbersome -// syntax, but it can be used with compositional functors. -// NOTE: The functor retuns a bool because msdev bombs during the -// composition if you return void. Once we upgrade to a newer -// compiler, the second unary_function template parameter can be set -// to void. -// -// Here's a snippet showing how you use this object: -// -// typedef std::map map_type; -// map_type widget_map; -// ... // add elements -// // delete them all -// for_each(widget_map.begin(), -// widget_map.end(), -// llcompose1(DeletePointerFunctor(), -// llselect2nd())); - -template -struct DeletePointerFunctor -{ - bool operator()(T* ptr) const - { - delete ptr; - return true; - } -}; - -// See notes about DeleteArray for why you should consider avoiding this. -template -struct DeleteArrayFunctor -{ - bool operator()(T* ptr) const - { - delete[] ptr; - return true; - } -}; - -// CopyNewPointer is a simple helper which accepts a pointer, and -// returns a new pointer built with the copy constructor. Example: -// -// transform(in.begin(), in.end(), out.end(), CopyNewPointer()); - -struct CopyNewPointer -{ - template T* operator()(const T* ptr) const - { - return new T(*ptr); - } -}; - -template -void delete_and_clear(std::list& list) -{ - std::for_each(list.begin(), list.end(), DeletePointer()); - list.clear(); -} - -template -void delete_and_clear(std::vector& vector) -{ - std::for_each(vector.begin(), vector.end(), DeletePointer()); - vector.clear(); -} - -template -void delete_and_clear(std::set& set) -{ - std::for_each(set.begin(), set.end(), DeletePointer()); - set.clear(); -} - -template -void delete_and_clear(std::map& map) -{ - std::for_each(map.begin(), map.end(), DeletePairedPointer()); - map.clear(); -} - -template -void delete_and_clear(T*& ptr) -{ - delete ptr; - ptr = NULL; -} - - -template -void delete_and_clear_array(T*& ptr) -{ - delete[] ptr; - ptr = NULL; -} - -// Simple function to help with finding pointers in maps. -// For example: -// typedef map_t; -// std::map foo; -// foo[18] = "there"; -// foo[2] = "hello"; -// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello" -// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL -template -inline T* get_ptr_in_map(const std::map& inmap, const K& key) -{ - // Typedef here avoids warnings because of new c++ naming rules. - typedef typename std::map::const_iterator map_iter; - map_iter iter = inmap.find(key); - if(iter == inmap.end()) - { - return NULL; - } - else - { - return iter->second; - } -}; - -// helper function which returns true if key is in inmap. -template -inline bool is_in_map(const std::map& inmap, const K& key) -{ - if(inmap.find(key) == inmap.end()) - { - return false; - } - else - { - return true; - } -} - -// Similar to get_ptr_in_map, but for any type with a valid T(0) constructor. -// To replace LLSkipMap getIfThere, use: -// get_if_there(map, key, 0) -// WARNING: Make sure default_value (generally 0) is not a valid map entry! -template -inline T get_if_there(const std::map& inmap, const K& key, T default_value) -{ - // Typedef here avoids warnings because of new c++ naming rules. - typedef typename std::map::const_iterator map_iter; - map_iter iter = inmap.find(key); - if(iter == inmap.end()) - { - return default_value; - } - else - { - return iter->second; - } -}; - -// Useful for replacing the removeObj() functionality of LLDynamicArray -// Example: -// for (std::vector::iterator iter = mList.begin(); iter != mList.end(); ) -// { -// if ((*iter)->isMarkedForRemoval()) -// iter = vector_replace_with_last(mList, iter); -// else -// ++iter; -// } -template -inline typename std::vector::iterator vector_replace_with_last(std::vector& invec, typename std::vector::iterator iter) -{ - typename std::vector::iterator last = invec.end(); --last; - if (iter == invec.end()) - { - return iter; - } - else if (iter == last) - { - invec.pop_back(); - return invec.end(); - } - else - { - *iter = *last; - invec.pop_back(); - return iter; - } -}; - -// Example: -// vector_replace_with_last(mList, x); -template -inline bool vector_replace_with_last(std::vector& invec, const T& val) -{ - typename std::vector::iterator iter = std::find(invec.begin(), invec.end(), val); - if (iter != invec.end()) - { - typename std::vector::iterator last = invec.end(); --last; - *iter = *last; - invec.pop_back(); - return true; - } - return false; -} - -// Append N elements to the vector and return a pointer to the first new element. -template -inline T* vector_append(std::vector& invec, S32 N) -{ - U32 sz = invec.size(); - invec.resize(sz+N); - return &(invec[sz]); -} - -// call function f to n members starting at first. similar to std::for_each -template -Function ll_for_n(InputIter first, Size n, Function f) -{ - for ( ; n > 0; --n, ++first) - f(*first); - return f; -} - -// copy first to result n times, incrementing each as we go -template -OutputIter ll_copy_n(InputIter first, Size n, OutputIter result) -{ - for ( ; n > 0; --n, ++result, ++first) - *result = *first; - return result; -} - -// set *result = op(*f) for n elements of f -template -OutputIter ll_transform_n( - InputIter first, - Size n, - OutputIter result, - UnaryOp op) -{ - for ( ; n > 0; --n, ++result, ++first) - *result = op(*first); - return result; -} - - - -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1996-1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - - -// helper to deal with the fact that MSDev does not package -// select... with the stl. Look up usage on the sgi website. - -template -struct _LLSelect1st -{ - const auto& operator()(const _Pair& __x) const { - return __x.first; - } -}; - -template -struct _LLSelect2nd -{ - const auto& operator()(const _Pair& __x) const { - return __x.second; - } -}; - -template struct llselect1st : public _LLSelect1st<_Pair> {}; -template struct llselect2nd : public _LLSelect2nd<_Pair> {}; - -// helper to deal with the fact that MSDev does not package -// compose... with the stl. Look up usage on the sgi website. - -template -class ll_unary_compose -{ -protected: - _Operation1 __op1; - _Operation2 __op2; -public: - ll_unary_compose(const _Operation1& __x, const _Operation2& __y) - : __op1(__x), __op2(__y) {} - template - auto - operator()(const _Op2Arg& __x) const { - return __op1(__op2(__x)); - } -}; - -template -inline ll_unary_compose<_Operation1,_Operation2> -llcompose1(const _Operation1& __op1, const _Operation2& __op2) -{ - return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2); -} - -template -class ll_binary_compose -{ -protected: - _Operation1 _M_op1; - _Operation2 _M_op2; - _Operation3 _M_op3; -public: - ll_binary_compose(const _Operation1& __x, const _Operation2& __y, - const _Operation3& __z) - : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } - template - auto - operator()(const OP2ARG& __x) const { - return _M_op1(_M_op2(__x), _M_op3(__x)); - } -}; - -template -inline ll_binary_compose<_Operation1, _Operation2, _Operation3> -llcompose2(const _Operation1& __op1, const _Operation2& __op2, - const _Operation3& __op3) -{ - return ll_binary_compose<_Operation1,_Operation2,_Operation3> - (__op1, __op2, __op3); -} - -// helpers to deal with the fact that MSDev does not package -// bind... with the stl. Again, this is from sgi. -template -class llbinder1st -{ -protected: - _Operation op; - _Arg1 value; -public: - llbinder1st(const _Operation& __x, const _Arg1& __y) - : op(__x), value(__y) {} - template - auto - operator()(const _Arg2& __x) const { - return op(value, __x); - } -}; - -template -inline auto -llbind1st(const _Operation& __oper, const _Tp& __x) -{ - return llbinder1st<_Operation, _Tp>(__oper, __x); -} - -template -class llbinder2nd -{ -protected: - _Operation op; - _Arg2 value; -public: - llbinder2nd(const _Operation& __x, - const _Arg2& __y) - : op(__x), value(__y) {} - template - auto - operator()(const _Arg1& __x) const { - return op(__x, value); - } -}; - -template -inline auto -llbind2nd(const _Operation& __oper, const _Tp& __x) -{ - return llbinder2nd<_Operation, _Tp>(__oper, __x); -} - -/** - * Compare std::type_info* pointers a la std::less. We break this out as a - * separate function for use in two different std::less specializations. - */ -inline -bool before(const std::type_info* lhs, const std::type_info* rhs) -{ -#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) - // If we're building on Linux with gcc, and it's either gcc 3.x or - // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on - // Mac too, and some people build with gcc on Windows (cygwin or mingw). - // On Linux, different load modules may produce different type_info* - // pointers for the same type. Have to compare name strings to get good - // results. - return strcmp(lhs->name(), rhs->name()) < 0; -#else // not Linux, or gcc 4.4+ - // Just use before(), as we normally would - return lhs->before(*rhs); -#endif -} - -/** - * Specialize std::less to use std::type_info::before(). - * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* - * because, on Linux, you might get different std::type_info* pointers for the - * same type (from different load modules)! - */ -namespace std -{ - template <> - struct less - { - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return before(lhs, rhs); - } - }; - - template <> - struct less - { - bool operator()(std::type_info* lhs, std::type_info* rhs) const - { - return before(lhs, rhs); - } - }; -} // std - - -/** - * Implementation for ll_template_cast() (q.v.). - * - * Default implementation: trying to cast two completely unrelated types - * returns 0. Typically you'd specify T and U as pointer types, but in fact T - * can be any type that can be initialized with 0. - */ -template -struct ll_template_cast_impl -{ - T operator()(U) - { - return 0; - } -}; - -/** - * ll_template_cast(some_value) is for use in a template function when - * some_value might be of arbitrary type, but you want to recognize type T - * specially. - * - * It's designed for use with pointer types. Example: - * @code - * struct SpecialClass - * { - * void someMethod(const std::string&) const; - * }; - * - * template - * void somefunc(const REALCLASS& instance) - * { - * const SpecialClass* ptr = ll_template_cast(&instance); - * if (ptr) - * { - * ptr->someMethod("Call method only available on SpecialClass"); - * } - * } - * @endcode - * - * Why is this better than dynamic_cast<>? Because unless OtherClass is - * polymorphic, the following won't even compile (gcc 4.0.1): - * @code - * OtherClass other; - * SpecialClass* ptr = dynamic_cast(&other); - * @endcode - * to say nothing of this: - * @code - * void function(int); - * SpecialClass* ptr = dynamic_cast(&function); - * @endcode - * ll_template_cast handles these kinds of cases by returning 0. - */ -template -T ll_template_cast(U value) -{ - return ll_template_cast_impl()(value); -} - -/** - * Implementation for ll_template_cast() (q.v.). - * - * Implementation for identical types: return same value. - */ -template -struct ll_template_cast_impl -{ - T operator()(T value) - { - return value; - } -}; - -/** - * LL_TEMPLATE_CONVERTIBLE(dest, source) asserts that, for a value @c s of - * type @c source, ll_template_cast(s) will return @c s -- - * presuming that @c source can be converted to @c dest by the normal rules of - * C++. - * - * By default, ll_template_cast(s) will return 0 unless @c s's - * type is literally identical to @c dest. (This is because of the - * straightforward application of template specialization rules.) That can - * lead to surprising results, e.g.: - * - * @code - * Foo myFoo; - * const Foo* fooptr = ll_template_cast(&myFoo); - * @endcode - * - * Here @c fooptr will be 0 because &myFoo is of type Foo* - * -- @em not const Foo*. (Declaring const Foo myFoo; would - * force the compiler to do the right thing.) - * - * More disappointingly: - * @code - * struct Base {}; - * struct Subclass: public Base {}; - * Subclass object; - * Base* ptr = ll_template_cast(&object); - * @endcode - * - * Here @c ptr will be 0 because &object is of type - * Subclass* rather than Base*. We @em want this cast to - * succeed, but without our help ll_template_cast can't recognize it. - * - * The following would suffice: - * @code - * LL_TEMPLATE_CONVERTIBLE(Base*, Subclass*); - * ... - * Base* ptr = ll_template_cast(&object); - * @endcode - * - * However, as noted earlier, this is easily fooled: - * @code - * const Base* ptr = ll_template_cast(&object); - * @endcode - * would still produce 0 because we haven't yet seen: - * @code - * LL_TEMPLATE_CONVERTIBLE(const Base*, Subclass*); - * @endcode - * - * @TODO - * This macro should use Boost type_traits facilities for stripping and - * re-adding @c const and @c volatile qualifiers so that invoking - * LL_TEMPLATE_CONVERTIBLE(dest, source) will automatically generate all - * permitted permutations. It's really not fair to the coder to require - * separate: - * @code - * LL_TEMPLATE_CONVERTIBLE(Base*, Subclass*); - * LL_TEMPLATE_CONVERTIBLE(const Base*, Subclass*); - * LL_TEMPLATE_CONVERTIBLE(const Base*, const Subclass*); - * @endcode - * - * (Naturally we omit LL_TEMPLATE_CONVERTIBLE(Base*, const Subclass*) - * because that's not permitted by normal C++ assignment anyway.) - */ -#define LL_TEMPLATE_CONVERTIBLE(DEST, SOURCE) \ -template <> \ -struct ll_template_cast_impl \ -{ \ - DEST operator()(SOURCE wrapper) \ - { \ - return wrapper; \ - } \ -} - - -#endif // LL_LLSTL_H +/** + * @file llstl.h + * @brief helper object & functions for use with the stl. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library 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; + * version 2.1 of the License only. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLSTL_H +#define LL_LLSTL_H + +#include "stdtypes.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef LL_LINUX +// For strcmp +#include +#endif +// Use to compare the first element only of a pair +// e.g. typedef std::set, compare_pair > some_pair_set_t; +template +struct compare_pair_first +{ + bool operator()(const std::pair& a, const std::pair& b) const + { + return a.first < b.first; + } +}; + +template +struct compare_pair_greater +{ + bool operator()(const std::pair& a, const std::pair& b) const + { + if (!(a.first < b.first)) + return true; + else if (!(b.first < a.first)) + return false; + else + return !(a.second < b.second); + } +}; + +// Use to compare the contents of two pointers (e.g. std::string*) +template +struct compare_pointer_contents +{ + typedef const T* Tptr; + bool operator()(const Tptr& a, const Tptr& b) const + { + return *a < *b; + } +}; + +// DeletePointer is a simple helper for deleting all pointers in a container. +// The general form is: +// +// std::for_each(cont.begin(), cont.end(), DeletePointer()); +// somemap.clear(); +// +// Don't forget to clear()! + +struct DeletePointer +{ + template void operator()(T* ptr) const + { + delete ptr; + } +}; +struct DeletePointerArray +{ + template void operator()(T* ptr) const + { + delete[] ptr; + } +}; + +// DeletePairedPointer is a simple helper for deleting all pointers in a map. +// The general form is: +// +// std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer()); +// somemap.clear(); // Don't leave dangling pointers around + +struct DeletePairedPointer +{ + template void operator()(T &ptr) const + { + delete ptr.second; + ptr.second = NULL; + } +}; +struct DeletePairedPointerArray +{ + template void operator()(T &ptr) const + { + delete[] ptr.second; + ptr.second = NULL; + } +}; + + +// Alternate version of the above so that has a more cumbersome +// syntax, but it can be used with compositional functors. +// NOTE: The functor retuns a bool because msdev bombs during the +// composition if you return void. Once we upgrade to a newer +// compiler, the second unary_function template parameter can be set +// to void. +// +// Here's a snippet showing how you use this object: +// +// typedef std::map map_type; +// map_type widget_map; +// ... // add elements +// // delete them all +// for_each(widget_map.begin(), +// widget_map.end(), +// llcompose1(DeletePointerFunctor(), +// llselect2nd())); + +template +struct DeletePointerFunctor +{ + bool operator()(T* ptr) const + { + delete ptr; + return true; + } +}; + +// See notes about DeleteArray for why you should consider avoiding this. +template +struct DeleteArrayFunctor +{ + bool operator()(T* ptr) const + { + delete[] ptr; + return true; + } +}; + +// CopyNewPointer is a simple helper which accepts a pointer, and +// returns a new pointer built with the copy constructor. Example: +// +// transform(in.begin(), in.end(), out.end(), CopyNewPointer()); + +struct CopyNewPointer +{ + template T* operator()(const T* ptr) const + { + return new T(*ptr); + } +}; + +template +void delete_and_clear(std::list& list) +{ + std::for_each(list.begin(), list.end(), DeletePointer()); + list.clear(); +} + +template +void delete_and_clear(std::vector& vector) +{ + std::for_each(vector.begin(), vector.end(), DeletePointer()); + vector.clear(); +} + +template +void delete_and_clear(std::set& set) +{ + std::for_each(set.begin(), set.end(), DeletePointer()); + set.clear(); +} + +template +void delete_and_clear(std::map& map) +{ + std::for_each(map.begin(), map.end(), DeletePairedPointer()); + map.clear(); +} + +template +void delete_and_clear(T*& ptr) +{ + delete ptr; + ptr = NULL; +} + + +template +void delete_and_clear_array(T*& ptr) +{ + delete[] ptr; + ptr = NULL; +} + +// Simple function to help with finding pointers in maps. +// For example: +// typedef map_t; +// std::map foo; +// foo[18] = "there"; +// foo[2] = "hello"; +// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello" +// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL +template +inline T* get_ptr_in_map(const std::map& inmap, const K& key) +{ + // Typedef here avoids warnings because of new c++ naming rules. + typedef typename std::map::const_iterator map_iter; + map_iter iter = inmap.find(key); + if(iter == inmap.end()) + { + return NULL; + } + else + { + return iter->second; + } +}; + +// helper function which returns true if key is in inmap. +template +inline bool is_in_map(const std::map& inmap, const K& key) +{ + if(inmap.find(key) == inmap.end()) + { + return false; + } + else + { + return true; + } +} + +// Similar to get_ptr_in_map, but for any type with a valid T(0) constructor. +// To replace LLSkipMap getIfThere, use: +// get_if_there(map, key, 0) +// WARNING: Make sure default_value (generally 0) is not a valid map entry! +template +inline T get_if_there(const std::map& inmap, const K& key, T default_value) +{ + // Typedef here avoids warnings because of new c++ naming rules. + typedef typename std::map::const_iterator map_iter; + map_iter iter = inmap.find(key); + if(iter == inmap.end()) + { + return default_value; + } + else + { + return iter->second; + } +}; + +// Useful for replacing the removeObj() functionality of LLDynamicArray +// Example: +// for (std::vector::iterator iter = mList.begin(); iter != mList.end(); ) +// { +// if ((*iter)->isMarkedForRemoval()) +// iter = vector_replace_with_last(mList, iter); +// else +// ++iter; +// } +template +inline typename std::vector::iterator vector_replace_with_last(std::vector& invec, typename std::vector::iterator iter) +{ + typename std::vector::iterator last = invec.end(); --last; + if (iter == invec.end()) + { + return iter; + } + else if (iter == last) + { + invec.pop_back(); + return invec.end(); + } + else + { + *iter = *last; + invec.pop_back(); + return iter; + } +}; + +// Example: +// vector_replace_with_last(mList, x); +template +inline bool vector_replace_with_last(std::vector& invec, const T& val) +{ + typename std::vector::iterator iter = std::find(invec.begin(), invec.end(), val); + if (iter != invec.end()) + { + typename std::vector::iterator last = invec.end(); --last; + *iter = *last; + invec.pop_back(); + return true; + } + return false; +} + +// Append N elements to the vector and return a pointer to the first new element. +template +inline T* vector_append(std::vector& invec, S32 N) +{ + U32 sz = invec.size(); + invec.resize(sz+N); + return &(invec[sz]); +} + +// call function f to n members starting at first. similar to std::for_each +template +Function ll_for_n(InputIter first, Size n, Function f) +{ + for ( ; n > 0; --n, ++first) + f(*first); + return f; +} + +// copy first to result n times, incrementing each as we go +template +OutputIter ll_copy_n(InputIter first, Size n, OutputIter result) +{ + for ( ; n > 0; --n, ++result, ++first) + *result = *first; + return result; +} + +// set *result = op(*f) for n elements of f +template +OutputIter ll_transform_n( + InputIter first, + Size n, + OutputIter result, + UnaryOp op) +{ + for ( ; n > 0; --n, ++result, ++first) + *result = op(*first); + return result; +} + + + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + + +// helper to deal with the fact that MSDev does not package +// select... with the stl. Look up usage on the sgi website. + +template +struct _LLSelect1st +{ + const auto& operator()(const _Pair& __x) const { + return __x.first; + } +}; + +template +struct _LLSelect2nd +{ + const auto& operator()(const _Pair& __x) const { + return __x.second; + } +}; + +template struct llselect1st : public _LLSelect1st<_Pair> {}; +template struct llselect2nd : public _LLSelect2nd<_Pair> {}; + +// helper to deal with the fact that MSDev does not package +// compose... with the stl. Look up usage on the sgi website. + +template +class ll_unary_compose +{ +protected: + _Operation1 __op1; + _Operation2 __op2; +public: + ll_unary_compose(const _Operation1& __x, const _Operation2& __y) + : __op1(__x), __op2(__y) {} + template + auto + operator()(const _Op2Arg& __x) const { + return __op1(__op2(__x)); + } +}; + +template +inline ll_unary_compose<_Operation1,_Operation2> +llcompose1(const _Operation1& __op1, const _Operation2& __op2) +{ + return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2); +} + +template +class ll_binary_compose +{ +protected: + _Operation1 _M_op1; + _Operation2 _M_op2; + _Operation3 _M_op3; +public: + ll_binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } + template + auto + operator()(const OP2ARG& __x) const { + return _M_op1(_M_op2(__x), _M_op3(__x)); + } +}; + +template +inline ll_binary_compose<_Operation1, _Operation2, _Operation3> +llcompose2(const _Operation1& __op1, const _Operation2& __op2, + const _Operation3& __op3) +{ + return ll_binary_compose<_Operation1,_Operation2,_Operation3> + (__op1, __op2, __op3); +} + +// helpers to deal with the fact that MSDev does not package +// bind... with the stl. Again, this is from sgi. +template +class llbinder1st +{ +protected: + _Operation op; + _Arg1 value; +public: + llbinder1st(const _Operation& __x, const _Arg1& __y) + : op(__x), value(__y) {} + template + auto + operator()(const _Arg2& __x) const { + return op(value, __x); + } +}; + +template +inline auto +llbind1st(const _Operation& __oper, const _Tp& __x) +{ + return llbinder1st<_Operation, _Tp>(__oper, __x); +} + +template +class llbinder2nd +{ +protected: + _Operation op; + _Arg2 value; +public: + llbinder2nd(const _Operation& __x, + const _Arg2& __y) + : op(__x), value(__y) {} + template + auto + operator()(const _Arg1& __x) const { + return op(__x, value); + } +}; + +template +inline auto +llbind2nd(const _Operation& __oper, const _Tp& __x) +{ + return llbinder2nd<_Operation, _Tp>(__oper, __x); +} + +/** + * Compare std::type_info* pointers a la std::less. We break this out as a + * separate function for use in two different std::less specializations. + */ +inline +bool before(const std::type_info* lhs, const std::type_info* rhs) +{ +#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + // If we're building on Linux with gcc, and it's either gcc 3.x or + // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on + // Mac too, and some people build with gcc on Windows (cygwin or mingw). + // On Linux, different load modules may produce different type_info* + // pointers for the same type. Have to compare name strings to get good + // results. + return strcmp(lhs->name(), rhs->name()) < 0; +#else // not Linux, or gcc 4.4+ + // Just use before(), as we normally would + return lhs->before(*rhs); +#endif +} + +/** + * Specialize std::less to use std::type_info::before(). + * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* + * because, on Linux, you might get different std::type_info* pointers for the + * same type (from different load modules)! + */ +namespace std +{ + template <> + struct less + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; + + template <> + struct less + { + bool operator()(std::type_info* lhs, std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; +} // std + + +/** + * Implementation for ll_template_cast() (q.v.). + * + * Default implementation: trying to cast two completely unrelated types + * returns 0. Typically you'd specify T and U as pointer types, but in fact T + * can be any type that can be initialized with 0. + */ +template +struct ll_template_cast_impl +{ + T operator()(U) + { + return 0; + } +}; + +/** + * ll_template_cast(some_value) is for use in a template function when + * some_value might be of arbitrary type, but you want to recognize type T + * specially. + * + * It's designed for use with pointer types. Example: + * @code + * struct SpecialClass + * { + * void someMethod(const std::string&) const; + * }; + * + * template + * void somefunc(const REALCLASS& instance) + * { + * const SpecialClass* ptr = ll_template_cast(&instance); + * if (ptr) + * { + * ptr->someMethod("Call method only available on SpecialClass"); + * } + * } + * @endcode + * + * Why is this better than dynamic_cast<>? Because unless OtherClass is + * polymorphic, the following won't even compile (gcc 4.0.1): + * @code + * OtherClass other; + * SpecialClass* ptr = dynamic_cast(&other); + * @endcode + * to say nothing of this: + * @code + * void function(int); + * SpecialClass* ptr = dynamic_cast(&function); + * @endcode + * ll_template_cast handles these kinds of cases by returning 0. + */ +template +T ll_template_cast(U value) +{ + return ll_template_cast_impl()(value); +} + +/** + * Implementation for ll_template_cast() (q.v.). + * + * Implementation for identical types: return same value. + */ +template +struct ll_template_cast_impl +{ + T operator()(T value) + { + return value; + } +}; + +/** + * LL_TEMPLATE_CONVERTIBLE(dest, source) asserts that, for a value @c s of + * type @c source, ll_template_cast(s) will return @c s -- + * presuming that @c source can be converted to @c dest by the normal rules of + * C++. + * + * By default, ll_template_cast(s) will return 0 unless @c s's + * type is literally identical to @c dest. (This is because of the + * straightforward application of template specialization rules.) That can + * lead to surprising results, e.g.: + * + * @code + * Foo myFoo; + * const Foo* fooptr = ll_template_cast(&myFoo); + * @endcode + * + * Here @c fooptr will be 0 because &myFoo is of type Foo* + * -- @em not const Foo*. (Declaring const Foo myFoo; would + * force the compiler to do the right thing.) + * + * More disappointingly: + * @code + * struct Base {}; + * struct Subclass: public Base {}; + * Subclass object; + * Base* ptr = ll_template_cast(&object); + * @endcode + * + * Here @c ptr will be 0 because &object is of type + * Subclass* rather than Base*. We @em want this cast to + * succeed, but without our help ll_template_cast can't recognize it. + * + * The following would suffice: + * @code + * LL_TEMPLATE_CONVERTIBLE(Base*, Subclass*); + * ... + * Base* ptr = ll_template_cast(&object); + * @endcode + * + * However, as noted earlier, this is easily fooled: + * @code + * const Base* ptr = ll_template_cast(&object); + * @endcode + * would still produce 0 because we haven't yet seen: + * @code + * LL_TEMPLATE_CONVERTIBLE(const Base*, Subclass*); + * @endcode + * + * @TODO + * This macro should use Boost type_traits facilities for stripping and + * re-adding @c const and @c volatile qualifiers so that invoking + * LL_TEMPLATE_CONVERTIBLE(dest, source) will automatically generate all + * permitted permutations. It's really not fair to the coder to require + * separate: + * @code + * LL_TEMPLATE_CONVERTIBLE(Base*, Subclass*); + * LL_TEMPLATE_CONVERTIBLE(const Base*, Subclass*); + * LL_TEMPLATE_CONVERTIBLE(const Base*, const Subclass*); + * @endcode + * + * (Naturally we omit LL_TEMPLATE_CONVERTIBLE(Base*, const Subclass*) + * because that's not permitted by normal C++ assignment anyway.) + */ +#define LL_TEMPLATE_CONVERTIBLE(DEST, SOURCE) \ +template <> \ +struct ll_template_cast_impl \ +{ \ + DEST operator()(SOURCE wrapper) \ + { \ + return wrapper; \ + } \ +} + + +#endif // LL_LLSTL_H -- cgit v1.2.3 From b42f9d836b4c0f7fbd4bdae1734021e2a09fdbe8 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 1 Jun 2024 15:49:26 +0200 Subject: Re-enable a lot of compiler warnings for MSVC and address the C4267 "possible loss of precision" warnings --- indra/llcommon/llstl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llstl.h') diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 67b4c141af..1b52d94258 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -326,7 +326,7 @@ inline bool vector_replace_with_last(std::vector& invec, const T& val) template inline T* vector_append(std::vector& invec, S32 N) { - U32 sz = invec.size(); + auto sz = invec.size(); invec.resize(sz+N); return &(invec[sz]); } -- cgit v1.2.3