📄 functional
字号:
// Retrieve a pointer to the function object static _Functor* _M_get_pointer(const _Any_data& __source) { const _Functor* __ptr = __stored_locally? &__source._M_access<_Functor>() /* have stored a pointer */ : __source._M_access<_Functor*>(); return const_cast<_Functor*>(__ptr); } // Clone a location-invariant function object that fits within // an _Any_data structure. static void _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) { new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); } // Clone a function object that is not location-invariant or // that cannot fit into an _Any_data structure. static void _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) { __dest._M_access<_Functor*>() = new _Functor(*__source._M_access<_Functor*>()); } // Destroying a location-invariant object may still require // destruction. static void _M_destroy(_Any_data& __victim, true_type) { __victim._M_access<_Functor>().~_Functor(); } // Destroying an object located on the heap. static void _M_destroy(_Any_data& __victim, false_type) { delete __victim._M_access<_Functor*>(); } public: static bool _M_manager(_Any_data& __dest, const _Any_data& __source, _Manager_operation __op) { switch (__op) { case __get_type_info: __dest._M_access<const type_info*>() = &typeid(_Functor); break; case __get_functor_ptr: __dest._M_access<_Functor*>() = _M_get_pointer(__source); break; case __clone_functor: _M_clone(__dest, __source, _Local_storage()); break; case __destroy_functor: _M_destroy(__dest, _Local_storage()); break; } return false; } static void _M_init_functor(_Any_data& __functor, const _Functor& __f) { _M_init_functor(__functor, __f, _Local_storage()); } template<typename _Signature> static bool _M_not_empty_function(const function<_Signature>& __f) { return __f; } template<typename _Tp> static bool _M_not_empty_function(const _Tp*& __fp) { return __fp; } template<typename _Class, typename _Tp> static bool _M_not_empty_function(_Tp _Class::* const& __mp) { return __mp; } template<typename _Tp> static bool _M_not_empty_function(const _Tp&) { return true; } private: static void _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) { new (__functor._M_access()) _Functor(__f); } static void _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) { __functor._M_access<_Functor*>() = new _Functor(__f); } }; template<typename _Functor> class _Ref_manager : public _Base_manager<_Functor*> { typedef _Function_base::_Base_manager<_Functor*> _Base; public: static bool _M_manager(_Any_data& __dest, const _Any_data& __source, _Manager_operation __op) { switch (__op) { case __get_type_info: __dest._M_access<const type_info*>() = &typeid(_Functor); break; case __get_functor_ptr: __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); return is_const<_Functor>::value; break; default: _Base::_M_manager(__dest, __source, __op); } return false; } static void _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) { // TBD: Use address_of function instead _Base::_M_init_functor(__functor, &__f.get()); } }; _Function_base() : _M_manager(0) { } ~_Function_base() { if (_M_manager) { _M_manager(_M_functor, _M_functor, __destroy_functor); } } bool _M_empty() const { return !_M_manager; } typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, _Manager_operation); _Any_data _M_functor; _Manager_type _M_manager; }; // [3.7.2.7] null pointer comparisons /** * @brief Compares a polymorphic function object wrapper against 0 * (the NULL pointer). * @returns @c true if the wrapper has no target, @c false otherwise * * This function will not throw an exception. */ template<typename _Signature> inline bool operator==(const function<_Signature>& __f, _M_clear_type*) { return !__f; } /** * @overload */ template<typename _Signature> inline bool operator==(_M_clear_type*, const function<_Signature>& __f) { return !__f; } /** * @brief Compares a polymorphic function object wrapper against 0 * (the NULL pointer). * @returns @c false if the wrapper has no target, @c true otherwise * * This function will not throw an exception. */ template<typename _Signature> inline bool operator!=(const function<_Signature>& __f, _M_clear_type*) { return __f; } /** * @overload */ template<typename _Signature> inline bool operator!=(_M_clear_type*, const function<_Signature>& __f) { return __f; } // [3.7.2.8] specialized algorithms /** * @brief Swap the targets of two polymorphic function object wrappers. * * This function will not throw an exception. */ template<typename _Signature> inline void swap(function<_Signature>& __x, function<_Signature>& __y) { __x.swap(__y); }#define _GLIBCXX_JOIN(X,Y) _GLIBCXX_JOIN2( X , Y )#define _GLIBCXX_JOIN2(X,Y) _GLIBCXX_JOIN3(X,Y)#define _GLIBCXX_JOIN3(X,Y) X##Y#define _GLIBCXX_REPEAT_HEADER <tr1/functional_iterate.h>#include <tr1/repeat.h>#undef _GLIBCXX_REPEAT_HEADER#undef _GLIBCXX_JOIN3#undef _GLIBCXX_JOIN2#undef _GLIBCXX_JOIN // Definition of default hash function std::tr1::hash<>. The types for // which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR. template<typename T> struct hash;#define tr1_hashtable_define_trivial_hash(T) \ template<> \ struct hash<T> \ : public std::unary_function<T, std::size_t> \ { \ std::size_t \ operator()(T val) const \ { return static_cast<std::size_t>(val); } \ } tr1_hashtable_define_trivial_hash(bool); tr1_hashtable_define_trivial_hash(char); tr1_hashtable_define_trivial_hash(signed char); tr1_hashtable_define_trivial_hash(unsigned char); tr1_hashtable_define_trivial_hash(wchar_t); tr1_hashtable_define_trivial_hash(short); tr1_hashtable_define_trivial_hash(int); tr1_hashtable_define_trivial_hash(long); tr1_hashtable_define_trivial_hash(unsigned short); tr1_hashtable_define_trivial_hash(unsigned int); tr1_hashtable_define_trivial_hash(unsigned long);#undef tr1_hashtable_define_trivial_hash template<typename T> struct hash<T*> : public std::unary_function<T*, std::size_t> { std::size_t operator()(T* p) const { return reinterpret_cast<std::size_t>(p); } }; // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) // (used by the next specializations of std::tr1::hash<>) // Dummy generic implementation (for sizeof(size_t) != 4, 8). template<std::size_t = sizeof(std::size_t)> struct Fnv_hash { static std::size_t hash(const char* first, std::size_t length) { std::size_t result = 0; for (; length > 0; --length) result = (result * 131) + *first++; return result; } }; template<> struct Fnv_hash<4> { static std::size_t hash(const char* first, std::size_t length) { std::size_t result = static_cast<std::size_t>(2166136261UL); for (; length > 0; --length) { result ^= (std::size_t)*first++; result *= 16777619UL; } return result; } }; template<> struct Fnv_hash<8> { static std::size_t hash(const char* first, std::size_t length) { std::size_t result = static_cast<std::size_t>(14695981039346656037ULL); for (; length > 0; --length) { result ^= (std::size_t)*first++; result *= 1099511628211ULL; } return result; } }; // XXX String and floating point hashes probably shouldn't be inline // member functions, since are nontrivial. Once we have the framework // for TR1 .cc files, these should go in one. template<> struct hash<std::string> : public std::unary_function<std::string, std::size_t> { std::size_t operator()(const std::string& s) const { return Fnv_hash<>::hash(s.data(), s.length()); } };#ifdef _GLIBCXX_USE_WCHAR_T template<> struct hash<std::wstring> : public std::unary_function<std::wstring, std::size_t> { std::size_t operator()(const std::wstring& s) const { return Fnv_hash<>::hash(reinterpret_cast<const char*>(s.data()), s.length() * sizeof(wchar_t)); } };#endif template<> struct hash<float> : public std::unary_function<float, std::size_t> { std::size_t operator()(float fval) const { std::size_t result = 0; // 0 and -0 both hash to zero. if (fval != 0.0f) result = Fnv_hash<>::hash(reinterpret_cast<const char*>(&fval), sizeof(fval)); return result; } }; template<> struct hash<double> : public std::unary_function<double, std::size_t> { std::size_t operator()(double dval) const { std::size_t result = 0; // 0 and -0 both hash to zero. if (dval != 0.0) result = Fnv_hash<>::hash(reinterpret_cast<const char*>(&dval), sizeof(dval)); return result; } }; // For long double, careful with random padding bits (e.g., on x86, // 10 bytes -> 12 bytes) and resort to frexp. template<> struct hash<long double> : public std::unary_function<long double, std::size_t> { std::size_t operator()(long double ldval) const { std::size_t result = 0; int exponent; ldval = std::frexp(ldval, &exponent); ldval = ldval < 0.0l ? -(ldval + 0.5l) : ldval; const long double mult = std::numeric_limits<std::size_t>::max() + 1.0l; ldval *= mult; // Try to use all the bits of the mantissa (really necessary only // on 32-bit targets, at least for 80-bit floating point formats). const std::size_t hibits = (std::size_t)ldval; ldval = (ldval - (long double)hibits) * mult; const std::size_t coeff = (std::numeric_limits<std::size_t>::max() / std::numeric_limits<long double>::max_exponent); result = hibits + (std::size_t)ldval + coeff * exponent; return result; } };}}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -