no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

79
cocos/base/std/any.h Normal file
View File

@@ -0,0 +1,79 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#ifdef USE_CXX_17
#include <any>
namespace ccstd {
using std::any;
using std::any_cast;
} // namespace ccstd
#else
#include "boost/any.hpp"
namespace ccstd {
class any : public boost::any { // NOLINT // use std style
public:
using boost::any::any;
inline bool has_value() const noexcept { // NOLINT // use std style
return !this->empty();
}
};
template <typename ValueType>
inline ValueType *any_cast(any *operand) noexcept { // NOLINT // use std style
return boost::any_cast<ValueType>(operand);
}
template <typename ValueType>
inline const ValueType *any_cast(const any *operand) noexcept { // NOLINT // use std style
return boost::any_cast<ValueType>(operand);
}
template <typename ValueType>
inline ValueType any_cast(any &operand) { // NOLINT // use std style
return boost::any_cast<ValueType>(operand);
}
template <typename ValueType>
inline ValueType any_cast(const any &operand) { // NOLINT // use std style
return boost::any_cast<ValueType>(operand);
}
template <typename ValueType>
inline ValueType any_cast(any &&operand) { // NOLINT // use std style
return boost::any_cast<ValueType>(operand);
}
} // namespace ccstd
#endif

View File

@@ -0,0 +1,31 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <array>
namespace ccstd {
using std::array;
} // namespace ccstd

View File

@@ -0,0 +1,37 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <deque>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::deque;
namespace pmr {
template <class T>
using deque = std::deque<T, boost::container::pmr::polymorphic_allocator<T>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,37 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <list>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::list;
namespace pmr {
template <class T>
using list = std::list<T, boost::container::pmr::polymorphic_allocator<T>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,38 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <map>
#include <utility>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::map;
namespace pmr {
template <class Key, class T, class Compare = std::less<Key>>
using map = std::map<Key, T, Compare, boost::container::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,37 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <queue>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::queue;
namespace pmr {
template <class T>
using queue = std::queue<T, boost::container::pmr::polymorphic_allocator<T>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,39 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
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.
****************************************************************************/
#pragma once
#include <set>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::set;
namespace pmr {
template <
class Key,
class Compare = std::less<Key>>
using set = std::set<Key, Compare, boost::container::pmr::polymorphic_allocator<Key>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,36 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <string>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::string;
namespace pmr {
using string = std::basic_string<char, std::char_traits<char>, boost::container::pmr::polymorphic_allocator<char>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,51 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <unordered_map>
#include <utility>
#include "base/std/hash/hash_fwd.hpp"
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::unordered_map;
using std::unordered_multimap;
namespace pmr {
template <
class Key,
class T,
class Hash = ccstd::hash<Key>,
class Pred = std::equal_to<Key>>
using unordered_map = std::unordered_map<Key, T, Hash, Pred, boost::container::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
template <
class Key,
class T,
class Hash = ccstd::hash<Key>,
class Pred = std::equal_to<Key>>
using unordered_multimap = std::unordered_multimap<Key, T, Hash, Pred, boost::container::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
} // namespace pmr
} // namespace ccstd

View File

@@ -0,0 +1,40 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
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.
****************************************************************************/
#pragma once
#include <unordered_set>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::unordered_set;
namespace pmr {
template <
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>>
using unordered_set = std::unordered_set<Key, Hash, KeyEqual, boost::container::pmr::polymorphic_allocator<Key>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,37 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#include <vector>
#include "boost/container/pmr/polymorphic_allocator.hpp"
namespace ccstd {
using std::vector;
namespace pmr {
template <class T>
using vector = std::vector<T, boost::container::pmr::polymorphic_allocator<T>>;
}
} // namespace ccstd

View File

@@ -0,0 +1,336 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(CCSTD_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
#define CCSTD_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
// sufficiently good floating point support to not require any
// workarounds.
//
// When set to 0, the library tries to automatically
// use the best available implementation. This normally works well, but
// breaks when ambiguities are created by odd namespacing of the functions.
//
// Note that if this is set to 0, the library should still take full
// advantage of the platform's floating point support.
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__LIBCOMO__)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// Rogue Wave library:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(_LIBCPP_VERSION)
// libc++
# define BOOST_HASH_CONFORMANT_FLOATS 1
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
// GNU libstdc++ 3
# if defined(__GNUC__) && __GNUC__ >= 4
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(__STL_CONFIG_H)
// generic SGI STL
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__MSL_CPP__)
// MSL standard lib:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__IBMCPP__)
// VACPP std lib (probably conformant for much earlier version).
# if __IBMCPP__ >= 1210
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(MSIPL_COMPILE_H)
// Modena C++ standard library
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library (this has to appear after any possible replacement libraries):
# if _CPPLIB_VER >= 405
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#else
# define BOOST_HASH_CONFORMANT_FLOATS 0
#endif
#if BOOST_HASH_CONFORMANT_FLOATS
// The standard library is known to be compliant, so don't use the
// configuration mechanism.
namespace ccstd {
namespace hash_detail {
template <typename Float>
struct call_ldexp {
typedef Float float_type;
inline Float operator()(Float x, int y) const {
return std::ldexp(x, y);
}
};
template <typename Float>
struct call_frexp {
typedef Float float_type;
inline Float operator()(Float x, int* y) const {
return std::frexp(x, y);
}
};
template <typename Float>
struct select_hash_type
{
typedef Float type;
};
}
}
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// The following tries to automatically detect which are available.
namespace ccstd {
namespace hash_detail {
// Returned by dummy versions of the float functions.
struct not_found {
// Implicitly convertible to float and long double in order to avoid
// a compile error when the dummy float functions are used.
inline operator float() const { return 0; }
inline operator long double() const { return 0; }
};
// A type for detecting the return type of functions.
template <typename T> struct is;
template <> struct is<float> { char x[10]; };
template <> struct is<double> { char x[20]; };
template <> struct is<long double> { char x[30]; };
template <> struct is<boost::hash_detail::not_found> { char x[40]; };
// Used to convert the return type of a function to a type for sizeof.
template <typename T> is<T> float_type(T);
// call_ldexp
//
// This will get specialized for float and long double
template <typename Float> struct call_ldexp
{
typedef double float_type;
inline double operator()(double a, int b) const
{
using namespace std;
return ldexp(a, b);
}
};
// call_frexp
//
// This will get specialized for float and long double
template <typename Float> struct call_frexp
{
typedef double float_type;
inline double operator()(double a, int* b) const
{
using namespace std;
return frexp(a, b);
}
};
}
}
// A namespace for dummy functions to detect when the actual function we want
// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
//
// AFAICT these have to be outside of the boost namespace, as if they're in
// the boost namespace they'll always be preferable to any other function
// (since the arguments are built in types, ADL can't be used).
namespace ccstd_hash_detect_float_functions {
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
}
// Macros for generating specializations of call_ldexp and call_frexp.
//
// check_cpp and check_c99 check if the C++ or C99 functions are available.
//
// Then the call_* functions select an appropriate implementation.
//
// I used c99_func in a few places just to get a unique name.
//
// Important: when using 'using namespace' at namespace level, include as
// little as possible in that namespace, as Visual C++ has an odd bug which
// can cause the namespace to be imported at the global level. This seems to
// happen mainly when there's a template in the same namesapce.
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
namespace ccstd_hash_detect_float_functions { \
template <class Float> \
boost::hash_detail::not_found c99_func(Float, type2); \
} \
\
namespace ccstd { \
namespace hash_detail { \
namespace c99_func##_detect { \
using namespace std; \
using namespace ccstd_hash_detect_float_functions; \
\
struct check { \
static type1 x; \
static type2 y; \
BOOST_STATIC_CONSTANT(bool, cpp = \
sizeof(float_type(cpp_func(x,y))) \
== sizeof(is<type1>)); \
BOOST_STATIC_CONSTANT(bool, c99 = \
sizeof(float_type(c99_func(x,y))) \
== sizeof(is<type1>)); \
}; \
} \
\
template <bool x> \
struct call_c99_##c99_func : \
boost::hash_detail::call_##cpp_func<double> {}; \
\
template <> \
struct call_c99_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return c99_func(a, b); \
} \
}; \
\
template <bool x> \
struct call_cpp_##c99_func : \
call_c99_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::c99 \
> {}; \
\
template <> \
struct call_cpp_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return cpp_func(a, b); \
} \
}; \
\
template <> \
struct call_##cpp_func<type1> : \
call_cpp_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::cpp \
> {}; \
} \
}
#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
namespace ccstd { \
namespace hash_detail { \
\
template <> \
struct call_##cpp_func<type1> { \
typedef type1 float_type; \
inline type1 operator()(type1 x, type2 y) const { \
return c99_func(x, y); \
} \
}; \
} \
}
#if defined(ldexpf)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
#endif
#if defined(ldexpl)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
#endif
#if defined(frexpf)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
#endif
#if defined(frexpl)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
#endif
#undef BOOST_HASH_CALL_FLOAT_MACRO
#undef BOOST_HASH_CALL_FLOAT_FUNC
namespace ccstd
{
namespace hash_detail
{
template <typename Float1, typename Float2>
struct select_hash_type_impl {
typedef double type;
};
template <>
struct select_hash_type_impl<float, float> {
typedef float type;
};
template <>
struct select_hash_type_impl<long double, long double> {
typedef long double type;
};
// select_hash_type
//
// If there is support for a particular floating point type, use that
// otherwise use double (there's always support for double).
template <typename Float>
struct select_hash_type : select_hash_type_impl<
BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
> {};
}
}
#endif // BOOST_HASH_CONFORMANT_FLOATS
#endif

View File

@@ -0,0 +1,271 @@
// Copyright 2005-2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(CCSTD_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
#define CCSTD_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include "base/std/hash/detail/float_functions.hpp"
#include "base/std/hash/detail/limits.hpp"
#include <boost/core/enable_if.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <cstring>
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
// Can we use fpclassify?
// STLport
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#define BOOST_HASH_USE_FPCLASSIFY 0
// GNU libstdc++ 3
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY 1
# else
# define BOOST_HASH_USE_FPCLASSIFY 0
# endif
// Everything else
#else
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
namespace ccstd
{
namespace hash_detail
{
inline void hash_float_combine(ccstd::hash_t& seed, ccstd::hash_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
////////////////////////////////////////////////////////////////////////
// Binary hash function
//
// Only used for floats with known iec559 floats, and certain values in
// numeric_limits
inline ccstd::hash_t hash_binary(char* ptr, ccstd::hash_t length)
{
ccstd::hash_t seed = 0;
if (length >= sizeof(ccstd::hash_t)) {
std::memcpy(&seed, ptr, sizeof(ccstd::hash_t));
length -= sizeof(ccstd::hash_t);
ptr += sizeof(ccstd::hash_t);
while(length >= sizeof(ccstd::hash_t)) {
ccstd::hash_t buffer = 0;
std::memcpy(&buffer, ptr, sizeof(ccstd::hash_t));
hash_float_combine(seed, buffer);
length -= sizeof(ccstd::hash_t);
ptr += sizeof(ccstd::hash_t);
}
}
if (length > 0) {
ccstd::hash_t buffer = 0;
std::memcpy(&buffer, ptr, length);
hash_float_combine(seed, buffer);
}
return seed;
}
template <typename Float, unsigned digits, unsigned max_exponent>
struct enable_binary_hash
{
BOOST_STATIC_CONSTANT(bool, value =
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == digits &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == max_exponent);
};
template <typename Float>
inline ccstd::hash_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 24, 128>::value,
ccstd::hash_t>::type)
{
return hash_binary((char*) &v, 4);
}
template <typename Float>
inline ccstd::hash_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 53, 1024>::value,
ccstd::hash_t>::type)
{
return hash_binary((char*) &v, 8);
}
template <typename Float>
inline ccstd::hash_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 64, 16384>::value,
ccstd::hash_t>::type)
{
return hash_binary((char*) &v, 10);
}
template <typename Float>
inline ccstd::hash_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 113, 16384>::value,
ccstd::hash_t>::type)
{
return hash_binary((char*) &v, 16);
}
////////////////////////////////////////////////////////////////////////
// Portable hash function
//
// Used as a fallback when the binary hash function isn't supported.
template <class T>
inline ccstd::hash_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
v = ldexp(v, limits<ccstd::hash_t>::digits);
ccstd::hash_t seed = static_cast<ccstd::hash_t>(v);
v -= static_cast<T>(seed);
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
ccstd::hash_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value
+ limits<ccstd::hash_t>::digits - 1)
/ limits<ccstd::hash_t>::digits;
for(ccstd::hash_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<ccstd::hash_t>::digits);
ccstd::hash_t part = static_cast<ccstd::hash_t>(v);
v -= static_cast<T>(part);
hash_float_combine(seed, part);
}
hash_float_combine(seed, static_cast<ccstd::hash_t>(exp));
return seed;
}
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
template <class T>
inline ccstd::hash_t float_hash_impl(T v, ...)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
#endif
}
}
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
namespace ccstd
{
namespace hash_detail
{
template <class T>
inline ccstd::hash_t float_hash_value(T v)
{
#if defined(fpclassify)
switch (fpclassify(v))
#elif BOOST_HASH_CONFORMANT_FLOATS
switch (std::fpclassify(v))
#else
using namespace std;
switch (fpclassify(v))
#endif
{
case FP_ZERO:
return 0;
case FP_INFINITE:
return (ccstd::hash_t)(v > 0 ? -1 : -2);
case FP_NAN:
return (ccstd::hash_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v, 0);
default:
BOOST_ASSERT(0);
return 0;
}
}
}
}
#else // !BOOST_HASH_USE_FPCLASSIFY
namespace ccstd
{
namespace hash_detail
{
template <class T>
inline bool is_zero(T v)
{
#if !defined(__GNUC__) && !defined(__clang__)
return v == 0;
#else
// GCC's '-Wfloat-equal' will complain about comparing
// v to 0, but because it disables warnings for system
// headers it won't complain if you use std::equal_to to
// compare with 0. Resulting in this silliness:
return std::equal_to<T>()(v, 0);
#endif
}
template <class T>
inline ccstd::hash_t float_hash_value(T v)
{
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
}
}
}
#endif // BOOST_HASH_USE_FPCLASSIFY
#undef BOOST_HASH_USE_FPCLASSIFY
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,62 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// On some platforms std::limits gives incorrect values for long double.
// This tries to work around them.
#if !defined(CCSTD_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define CCSTD_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/limits.hpp>
// On OpenBSD, numeric_limits is not reliable for long doubles, but
// the macros defined in <float.h> are and support long double when STLport
// doesn't.
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
#include <float.h>
#endif
namespace ccstd
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
template <>
struct limits<long double>
: std::numeric_limits<long double>
{
static long double epsilon() {
return LDBL_EPSILON;
}
static long double (max)() {
return LDBL_MAX;
}
static long double (min)() {
return LDBL_MIN;
}
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
#if defined(_STLP_NO_LONG_DOUBLE)
BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
#endif
};
#endif // __OpenBSD__
}
}
#endif

View File

@@ -0,0 +1,361 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
// This implements the extensions to the standard.
// It's undocumented, so you shouldn't use it....
#if !defined(CCSTD_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define CCSTD_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include "base/std/hash/hash.h"
#include <boost/detail/container_fwd.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/static_assert.hpp>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
# include <tuple>
#endif
#include <memory>
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
namespace ccstd
{
template <class A, class B>
hash_t hash_value(std::pair<A, B> const&);
template <class T, class A>
hash_t hash_value(std::vector<T, A> const&);
template <class T, class A>
hash_t hash_value(std::list<T, A> const& v);
template <class T, class A>
hash_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
hash_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
hash_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
hash_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
hash_t hash_value(std::multimap<K, T, C, A> const& v);
template <class T>
hash_t hash_value(std::complex<T> const&);
template <class A, class B>
hash_t hash_value(std::pair<A, B> const& v)
{
hash_t seed = 0;
ccstd::hash_combine(seed, v.first);
ccstd::hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
hash_t hash_value(std::vector<T, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class T, class A>
hash_t hash_value(std::list<T, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class T, class A>
hash_t hash_value(std::deque<T, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
hash_t hash_value(std::set<K, C, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
hash_t hash_value(std::multiset<K, C, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
hash_t hash_value(std::map<K, T, C, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
hash_t hash_value(std::multimap<K, T, C, A> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
template <class T>
hash_t hash_value(std::complex<T> const& v)
{
ccstd::hash<T> hasher;
hash_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
}
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
template <class T, std::size_t N>
hash_t hash_value(std::array<T, N> const& v)
{
return ccstd::hash_range(v.begin(), v.end());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
namespace hash_detail {
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
void>::type
hash_combine_tuple(hash_t&, T const&)
{
}
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
void>::type
hash_combine_tuple(hash_t& seed, T const& v)
{
ccstd::hash_combine(seed, std::get<I>(v));
ccstd::hash_detail::hash_combine_tuple<I + 1>(seed, v);
}
template <typename T>
inline hash_t hash_tuple(T const& v)
{
hash_t seed = 0;
ccstd::hash_detail::hash_combine_tuple<0>(seed, v);
return seed;
}
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... T>
inline hash_t hash_value(std::tuple<T...> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
#else
inline hash_t hash_value(std::tuple<> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0>
inline hash_t hash_value(std::tuple<A0> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1>
inline hash_t hash_value(std::tuple<A0, A1> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2>
inline hash_t hash_value(std::tuple<A0, A1, A2> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
inline hash_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v)
{
return ccstd::hash_detail::hash_tuple(v);
}
#endif
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
inline hash_t hash_value(std::shared_ptr<T> const& x) {
return ccstd::hash_value(x.get());
}
template <typename T, typename Deleter>
inline hash_t hash_value(std::unique_ptr<T, Deleter> const& x) {
return ccstd::hash_value(x.get());
}
#endif
//
// call_hash_impl
//
// On compilers without function template ordering, this deals with arrays.
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
{
template <bool IsArray>
struct call_hash_impl
{
template <class T>
struct inner
{
static hash_t call(T const& v)
{
using namespace ccstd;
return hash_value(v);
}
};
};
template <>
struct call_hash_impl<true>
{
template <class Array>
struct inner
{
static hash_t call(Array const& v)
{
const int size = sizeof(v) / sizeof(*v);
return ccstd::hash_range(v, v + size);
}
};
};
template <class T>
struct call_hash
: public call_hash_impl<ccstd::is_array<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//
// ccstd::hash
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: ccstd::hash_detail::hash_base<T>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
hash_t operator()(T const& val) const
{
return hash_value(val);
}
#else
hash_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T, unsigned int n> struct hash<T[n]>
: ccstd::hash_detail::hash_base<T[n]>
{
hash_t operator()(const T* val) const
{
return ccstd::hash_range(val, val+n);
}
};
#endif
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// On compilers without partial specialization, ccstd::hash<T>
// has already been declared to deal with pointers, so just
// need to supply the non-pointer version of hash_impl.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<false>
{
template <class T>
struct inner
: ccstd::hash_detail::hash_base<T>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
hash_t operator()(T const& val) const
{
return hash_value(val);
}
#else
hash_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
};
}
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
#endif

783
cocos/base/std/hash/hash.h Normal file
View File

@@ -0,0 +1,783 @@
// Copyright 2005-2014 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
//
// This also contains public domain code from MurmurHash. From the
// MurmurHash header:
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
#if !defined(CCSTD_FUNCTIONAL_HASH_HASH_HPP)
#define CCSTD_FUNCTIONAL_HASH_HASH_HPP
#include "boost/container_hash/hash.hpp"
#include "base/std/hash/hash_fwd.hpp"
#include <functional>
#include <iterator>
#include "base/std/hash/detail/hash_float.hpp"
#include <string>
#include <boost/limits.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/cstdint.hpp>
#include <climits>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
#include <system_error>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
// are always of range '0' to '4294967295'.
// Loop executes infinitely.
#endif
#endif
#if BOOST_WORKAROUND(__GNUC__, < 3) \
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define CCSTD_HASH_CHAR_TRAITS string_char_traits
#else
#define CCSTD_HASH_CHAR_TRAITS char_traits
#endif
#if defined(_MSC_VER)
# define CCSTD_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
#else
# define CCSTD_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
// Detect whether standard library has C++17 headers
#if !defined(CCSTD_HASH_CXX17)
# if defined(BOOST_MSVC)
# if defined(_HAS_CXX17) && _HAS_CXX17
# define CCSTD_HASH_CXX17 1
# endif
# elif defined(__cplusplus) && __cplusplus >= 201703
# define CCSTD_HASH_CXX17 1
# endif
#endif
#if !defined(CCSTD_HASH_CXX17)
# define CCSTD_HASH_CXX17 0
#endif
#if CCSTD_HASH_CXX17 && defined(__has_include)
# if !defined(CCSTD_HASH_HAS_STRING_VIEW) && __has_include(<string_view>)
# define CCSTD_HASH_HAS_STRING_VIEW 1
# endif
# if !defined(CCSTD_HASH_HAS_OPTIONAL) && __has_include(<optional>)
# define CCSTD_HASH_HAS_OPTIONAL 1
# endif
# if !defined(CCSTD_HASH_HAS_VARIANT) && __has_include(<variant>)
# define CCSTD_HASH_HAS_VARIANT 1
# endif
#endif
#if !defined(CCSTD_HASH_HAS_STRING_VIEW)
# define CCSTD_HASH_HAS_STRING_VIEW 0
#endif
#if !defined(CCSTD_HASH_HAS_OPTIONAL)
# define CCSTD_HASH_HAS_OPTIONAL 0
#endif
#if !defined(CCSTD_HASH_HAS_VARIANT)
# define CCSTD_HASH_HAS_VARIANT 0
#endif
#if CCSTD_HASH_HAS_STRING_VIEW
# include <string_view>
#endif
#if CCSTD_HASH_HAS_OPTIONAL
# include <optional>
#endif
#if CCSTD_HASH_HAS_VARIANT
# include <variant>
#endif
namespace ccstd
{
namespace hash_detail
{
#if defined(BOOST_NO_CXX98_FUNCTION_BASE)
template <typename T>
struct hash_base
{
typedef T argument_type;
typedef hash_t result_type;
};
#else
template <typename T>
struct hash_base : std::unary_function<T, hash_t> {};
#endif
struct enable_hash_value { typedef hash_t type; };
template <typename T> struct basic_numbers {};
template <typename T> struct long_numbers;
template <typename T> struct ulong_numbers;
template <typename T> struct float_numbers {};
template <> struct basic_numbers<bool> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<char> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned char> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<signed char> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<short> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned short> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<int> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned int> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<long> :
ccstd::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned long> :
ccstd::hash_detail::enable_hash_value {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <> struct basic_numbers<wchar_t> :
ccstd::hash_detail::enable_hash_value {};
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template <> struct basic_numbers<char16_t> :
ccstd::hash_detail::enable_hash_value {};
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template <> struct basic_numbers<char32_t> :
ccstd::hash_detail::enable_hash_value {};
#endif
// long_numbers is defined like this to allow for separate
// specialization for long_long and int128_type, in case
// they conflict.
template <typename T> struct long_numbers2 {};
template <typename T> struct ulong_numbers2 {};
template <typename T> struct long_numbers : long_numbers2<T> {};
template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
#if !defined(BOOST_NO_LONG_LONG)
template <> struct long_numbers<boost::long_long_type> :
ccstd::hash_detail::enable_hash_value {};
template <> struct ulong_numbers<boost::ulong_long_type> :
ccstd::hash_detail::enable_hash_value {};
#endif
#if defined(BOOST_HAS_INT128)
template <> struct long_numbers2<boost::int128_type> :
ccstd::hash_detail::enable_hash_value {};
template <> struct ulong_numbers2<boost::uint128_type> :
ccstd::hash_detail::enable_hash_value {};
#endif
template <> struct float_numbers<float> :
ccstd::hash_detail::enable_hash_value {};
template <> struct float_numbers<double> :
ccstd::hash_detail::enable_hash_value {};
template <> struct float_numbers<long double> :
ccstd::hash_detail::enable_hash_value {};
}
template <typename T>
typename ccstd::hash_detail::basic_numbers<T>::type hash_value(T);
template <typename T>
typename ccstd::hash_detail::long_numbers<T>::type hash_value(T);
template <typename T>
typename ccstd::hash_detail::ulong_numbers<T>::type hash_value(T);
template <typename T>
typename boost::enable_if<boost::is_enum<T>, hash_t>::type
hash_value(T);
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> hash_t hash_value(T* const&);
#else
template <class T> hash_t hash_value(T*);
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
hash_t hash_value(const T (&x)[N]);
template< class T, unsigned N >
hash_t hash_value(T (&x)[N]);
#endif
template <class Ch, class A>
hash_t hash_value(
std::basic_string<Ch, std::CCSTD_HASH_CHAR_TRAITS<Ch>, A> const&);
#if CCSTD_HASH_HAS_STRING_VIEW
template <class Ch>
hash_t hash_value(
std::basic_string_view<Ch, std::CCSTD_HASH_CHAR_TRAITS<Ch> > const&);
#endif
template <typename T>
typename ccstd::hash_detail::float_numbers<T>::type hash_value(T);
#if CCSTD_HASH_HAS_OPTIONAL
template <typename T>
hash_t hash_value(std::optional<T> const&);
#endif
#if CCSTD_HASH_HAS_VARIANT
hash_t hash_value(std::monostate);
template <typename... Types>
hash_t hash_value(std::variant<Types...> const&);
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
hash_t hash_value(std::type_index);
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
hash_t hash_value(std::error_code const&);
hash_t hash_value(std::error_condition const&);
#endif
// Implementation
namespace hash_detail
{
template <class T>
inline hash_t hash_value_signed(T val)
{
const unsigned int size_t_bits = std::numeric_limits<hash_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ static_cast<int>(size_t_bits);
hash_t seed = 0;
T positive = val < 0 ? -1 - val : val;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (hash_t) (positive >> i) + (seed<<6) + (seed>>2);
}
seed ^= (hash_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <class T>
inline hash_t hash_value_unsigned(T val)
{
const unsigned int size_t_bits = std::numeric_limits<hash_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ static_cast<int>(size_t_bits);
hash_t seed = 0;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (hash_t) (val >> i) + (seed<<6) + (seed>>2);
}
seed ^= (hash_t) val + (seed<<6) + (seed>>2);
return seed;
}
template<hash_t Bits> struct hash_combine_impl
{
template <typename SizeT>
inline static SizeT fn(SizeT seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
template<> struct hash_combine_impl<32>
{
inline static std::uint32_t fn(std::uint32_t h1, std::uint32_t k1)
{
const std::uint32_t c1 = 0xcc9e2d51;
const std::uint32_t c2 = 0x1b873593;
k1 *= c1;
k1 = CCSTD_FUNCTIONAL_HASH_ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = CCSTD_FUNCTIONAL_HASH_ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
return h1;
}
};
template<> struct hash_combine_impl<64>
{
inline static std::uint64_t fn(std::uint64_t h, std::uint64_t k)
{
const std::uint64_t m = (std::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995;
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
// Completely arbitrary number, to prevent 0's
// from hashing to 0.
h += 0xe6546b64;
return h;
}
};
}
template <typename T>
typename ccstd::hash_detail::basic_numbers<T>::type hash_value(T v)
{
return static_cast<hash_t>(v);
}
template <typename T>
typename ccstd::hash_detail::long_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_signed(v);
}
template <typename T>
typename ccstd::hash_detail::ulong_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_unsigned(v);
}
template <typename T>
typename boost::enable_if<boost::is_enum<T>, hash_t>::type
hash_value(T v)
{
return static_cast<hash_t>(v);
}
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> hash_t hash_value(T* const& v)
#else
template <class T> hash_t hash_value(T* v)
#endif
{
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
// for some reason ptrdiff_t on OpenVMS compiler with
// 64 bit is not 64 bit !!!
hash_t x = static_cast<hash_t>(
reinterpret_cast<long long int>(v));
#else
hash_t x = static_cast<hash_t>(
reinterpret_cast<std::ptrdiff_t>(v));
#endif
return x + (x >> 3);
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
template <class T>
inline void hash_combine(hash_t& seed, T const& v)
{
ccstd::hash<T> hasher;
seed = ccstd::hash_detail::hash_combine_impl<sizeof(hash_t) * CHAR_BIT>::fn(seed, hasher(v));
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class It>
inline hash_t hash_range(It first, It last)
{
hash_t seed = 0;
for(; first != last; ++first)
{
hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
}
return seed;
}
template <class It>
inline void hash_range(hash_t& seed, It first, It last)
{
for(; first != last; ++first)
{
hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
}
}
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template <class T>
inline hash_t hash_range(T* first, T* last)
{
hash_t seed = 0;
for(; first != last; ++first)
{
ccstd::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
template <class T>
inline void hash_range(hash_t& seed, T* first, T* last)
{
for(; first != last; ++first)
{
ccstd::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
inline hash_t hash_value(const T (&x)[N])
{
return hash_range(x, x + N);
}
template< class T, unsigned N >
inline hash_t hash_value(T (&x)[N])
{
return hash_range(x, x + N);
}
#endif
template <class Ch, class A>
inline hash_t hash_value(
std::basic_string<Ch, std::CCSTD_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
#if CCSTD_HASH_HAS_STRING_VIEW
template <class Ch>
inline hash_t hash_value(
std::basic_string_view<Ch, std::CCSTD_HASH_CHAR_TRAITS<Ch> > const& v)
{
return hash_range(v.begin(), v.end());
}
#endif
template <typename T>
typename ccstd::hash_detail::float_numbers<T>::type hash_value(T v)
{
return ccstd::hash_detail::float_hash_value(v);
}
#if CCSTD_HASH_HAS_OPTIONAL
template <typename T>
inline hash_t hash_value(std::optional<T> const& v) {
if (!v) {
// Arbitray value for empty optional.
return 0x12345678;
} else {
ccstd::hash<T> hf;
return hf(*v);
}
}
#endif
#if CCSTD_HASH_HAS_VARIANT
inline hash_t hash_value(std::monostate) {
return 0x87654321;
}
template <typename... Types>
inline hash_t hash_value(std::variant<Types...> const& v) {
hash_t seed = 0;
hash_combine(seed, v.index());
std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v);
return seed;
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline hash_t hash_value(std::type_index v)
{
size_t hash = v.hash_code();
#ifndef INTPTR_MAX
#error "no INTPTR_MAX"
#endif
#ifndef INT64_MAX
#error "no INT64_MAX"
#endif
#if INTPTR_MAX == INT64_MAX
hash = (hash >> 32) ^ (hash & 0xFFFFFFFF);
#endif
return static_cast<hash_t>(hash);
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
inline hash_t hash_value(std::error_code const& v) {
hash_t seed = 0;
hash_combine(seed, v.value());
hash_combine(seed, &v.category());
return seed;
}
inline hash_t hash_value(std::error_condition const& v) {
hash_t seed = 0;
hash_combine(seed, v.value());
hash_combine(seed, &v.category());
return seed;
}
#endif
//
// ccstd::hash
//
// Define the specializations required by the standard. The general purpose
// ccstd::hash is defined later in extensions.hpp if
// CCSTD_HASH_NO_EXTENSIONS is not defined.
// CCSTD_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// CCSTD_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by const reference.
//
// These are undefined later.
#define CCSTD_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public ccstd::hash_detail::hash_base<type> \
{ \
hash_t operator()(type v) const \
{ \
return ccstd::hash_value(v); \
} \
};
#define CCSTD_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public ccstd::hash_detail::hash_base<type> \
{ \
hash_t operator()(type const& v) const \
{ \
return ccstd::hash_value(v); \
} \
};
#define CCSTD_HASH_SPECIALIZE_TEMPLATE_REF(type) \
struct hash<type> \
: public ccstd::hash_detail::hash_base<type> \
{ \
hash_t operator()(type const& v) const \
{ \
return ccstd::hash_value(v); \
} \
};
CCSTD_HASH_SPECIALIZE(bool)
CCSTD_HASH_SPECIALIZE(char)
CCSTD_HASH_SPECIALIZE(signed char)
CCSTD_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
CCSTD_HASH_SPECIALIZE(wchar_t)
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
CCSTD_HASH_SPECIALIZE(char16_t)
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
CCSTD_HASH_SPECIALIZE(char32_t)
#endif
CCSTD_HASH_SPECIALIZE(short)
CCSTD_HASH_SPECIALIZE(unsigned short)
CCSTD_HASH_SPECIALIZE(int)
CCSTD_HASH_SPECIALIZE(unsigned int)
CCSTD_HASH_SPECIALIZE(long)
CCSTD_HASH_SPECIALIZE(unsigned long)
CCSTD_HASH_SPECIALIZE(float)
CCSTD_HASH_SPECIALIZE(double)
CCSTD_HASH_SPECIALIZE(long double)
CCSTD_HASH_SPECIALIZE_REF(std::string)
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
CCSTD_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
CCSTD_HASH_SPECIALIZE_REF(std::basic_string<char16_t>)
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
CCSTD_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
#endif
#if CCSTD_HASH_HAS_STRING_VIEW
CCSTD_HASH_SPECIALIZE_REF(std::string_view)
# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
CCSTD_HASH_SPECIALIZE_REF(std::wstring_view)
# endif
# if !defined(BOOST_NO_CXX11_CHAR16_T)
CCSTD_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
# endif
# if !defined(BOOST_NO_CXX11_CHAR32_T)
CCSTD_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
# endif
#endif
#if !defined(BOOST_NO_LONG_LONG)
CCSTD_HASH_SPECIALIZE(boost::long_long_type)
CCSTD_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#if defined(BOOST_HAS_INT128)
CCSTD_HASH_SPECIALIZE(boost::int128_type)
CCSTD_HASH_SPECIALIZE(boost::uint128_type)
#endif
#if CCSTD_HASH_HAS_OPTIONAL
template <typename T>
CCSTD_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
#endif
#if !defined(CCSTD_HASH_HAS_VARIANT)
template <typename... T>
CCSTD_HASH_SPECIALIZE_TEMPLATE_REF(std::variant<T...>)
CCSTD_HASH_SPECIALIZE(std::monostate)
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
CCSTD_HASH_SPECIALIZE(std::type_index)
#endif
#undef CCSTD_HASH_SPECIALIZE
#undef CCSTD_HASH_SPECIALIZE_REF
#undef CCSTD_HASH_SPECIALIZE_TEMPLATE_REF
// Specializing ccstd::hash for pointers.
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct hash<T*>
: public ccstd::hash_detail::hash_base<T*>
{
hash_t operator()(T* v) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
return ccstd::hash_value(v);
#else
hash_t x = static_cast<hash_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
#endif
}
};
#else
// For compilers without partial specialization, we define a
// ccstd::hash for all remaining types. But hash_impl is only defined
// for pointers in 'extensions.hpp' - so when CCSTD_HASH_NO_EXTENSIONS
// is defined there will still be a compile error for types not supported
// in the standard.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<true>
{
template <class T>
struct inner
: public ccstd::hash_detail::hash_base<T>
{
hash_t operator()(T val) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
return ccstd::hash_value(val);
#else
hash_t x = static_cast<hash_t>(
reinterpret_cast<std::ptrdiff_t>(val));
return x + (x >> 3);
#endif
}
};
};
}
template <class T> struct hash
: public ccstd::hash_detail::hash_impl<ccstd::is_pointer<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#undef CCSTD_HASH_CHAR_TRAITS
#undef CCSTD_FUNCTIONAL_HASH_ROTL32
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // CCSTD_FUNCTIONAL_HASH_HASH_HPP
// Include this outside of the include guards in case the file is included
// twice - once with CCSTD_HASH_NO_EXTENSIONS defined, and then with it
// undefined.
#if !defined(CCSTD_HASH_NO_EXTENSIONS) \
&& !defined(CCSTD_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#include "base/std/hash/extensions.hpp"
#endif

View File

@@ -0,0 +1,38 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(CCSTD_FUNCTIONAL_HASH_FWD_HPP)
#define CCSTD_FUNCTIONAL_HASH_FWD_HPP
#include <boost/config/workaround.hpp>
#include <cstddef>
#include <cstdint>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
namespace ccstd
{
using hash_t = std::uint32_t;
template <class T> struct hash;
template <class T> void hash_combine(hash_t& seed, T const& v);
template <class It> hash_t hash_range(It, It);
template <class It> void hash_range(hash_t&, It, It);
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template <class T> inline hash_t hash_range(T*, T*);
template <class T> inline void hash_range(hash_t&, T*, T*);
#endif
}
#endif

52
cocos/base/std/optional.h Normal file
View File

@@ -0,0 +1,52 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#ifdef USE_CXX_17
#include <optional>
namespace ccstd {
using std::nullopt;
using std::nullopt_t;
using std::optional;
}; // namespace ccstd
#else
#include "base/std/container/string.h"
#include "boost/none.hpp"
#include "boost/optional.hpp"
namespace ccstd {
using boost::optional;
using nullopt_t = boost::none_t;
const nullopt_t nullopt((boost::none_t::init_tag())); // NOLINT // use std style
}; // namespace ccstd
#endif

66
cocos/base/std/variant.h Normal file
View File

@@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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.
****************************************************************************/
#pragma once
#ifdef USE_CXX_17
#include <variant>
namespace ccstd {
using std::get;
using std::get_if;
using std::holds_alternative;
using std::in_place_index;
using std::monostate;
using std::variant;
using std::variant_alternative;
using std::variant_alternative_t;
using std::variant_size;
using std::variant_size_v;
using std::visit;
}; // namespace ccstd
#else
#include "boost/variant2/variant.hpp"
namespace ccstd {
using boost::variant2::get;
using boost::variant2::get_if;
using boost::variant2::holds_alternative;
using boost::variant2::in_place_index;
using boost::variant2::monostate;
using boost::variant2::variant;
using boost::variant2::variant_alternative;
using boost::variant2::variant_alternative_t;
using boost::variant2::variant_size;
using boost::variant2::variant_size_v;
using boost::variant2::visit;
}; // namespace ccstd
#endif