15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains utility functions and classes that help the 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation, and management of the Callback objects. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_CALLBACK_INTERNAL_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_CALLBACK_INTERNAL_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedVector; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BindStateBase is used to provide an opaque handle that the Callback 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class can use to represent a function object with bound arguments. It 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// behaves as an existential type that is used by a corresponding 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DoInvoke function to perform the function execution. This allows 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// us to shield the Callback class from the types of the bound argument via 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "type erasure." 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BindStateBase : public RefCountedThreadSafe<BindStateBase> { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class RefCountedThreadSafe<BindStateBase>; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BindStateBase() {} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds the Callback methods that don't require specialization to reduce 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// template bloat. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT CallbackBase { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if Callback is null (doesn't refer to anything). 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool is_null() const { return bind_state_.get() == NULL; } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the Callback into an uninitialized state. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In C++, it is safe to cast function pointers to function pointers of 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // another type. It is not okay to use void*. We create a InvokeFuncStorage 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that that can store our function pointer, and then cast it back to 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the original type on usage. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef void(*InvokeFuncStorage)(void); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this callback equals |other|. |other| may be null. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Equals(const CallbackBase& other) const; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow initializing of |bind_state_| via the constructor to avoid default 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialization of the scoped_refptr. We do not also initialize 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |polymorphic_invoke_| here because doing a normal assignment in the 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // derived Callback templates makes for much nicer compiler errors. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CallbackBase(BindStateBase* bind_state); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force the destructor to be instantiated inside this translation unit so 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that our subclasses will not get inlined versions. Avoids more template 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bloat. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CallbackBase(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<BindStateBase> bind_state_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokeFuncStorage polymorphic_invoke_; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A helper template to determine if given type is non-const move-only-type, 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// i.e. if a value of the given type should be passed via .Pass() in a 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// destructive way. 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <typename T> struct IsMoveOnlyType { 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) template <typename U> 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static YesType Test(const typename U::MoveOnlyTypeForCPP03*); 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) template <typename U> 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static NoType Test(...); 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static const bool value = sizeof(Test<T>(0)) == sizeof(YesType) && 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) !is_const<T>::value; 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a typetraits object that's used to take an argument type, and 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extract a suitable type for storing and forwarding arguments. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In particular, it strips off references, and converts arrays to 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointers for storage; and it avoids accidentally trying to create a 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "reference of a reference" if the argument is a reference type. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This array type becomes an issue for storage because we are passing bound 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters by const reference. In this case, we end up passing an actual 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// array type in the initializer list which C++ does not allow. This will 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// break passing of C-string literals. 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <typename T, bool is_move_only = IsMoveOnlyType<T>::value> 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackParamTraits { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const T& ForwardType; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T StorageType; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Storage should almost be impossible to trigger unless someone manually 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies type of the bind parameters. However, in case they do, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this will guard against us accidentally storing a reference parameter. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The ForwardType should only be used for unbound arguments. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct CallbackParamTraits<T&, false> { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T& ForwardType; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T StorageType; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that for array types, we implicitly add a const in the conversion. This 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// means that it is not possible to bind array arguments to functions that take 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-const pointer. Trying to specialize the template based on a "const 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// T[n]" does not seem to match correctly, so we are stuck with this 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restriction. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T, size_t n> 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct CallbackParamTraits<T[n], false> { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const T* ForwardType; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const T* StorageType; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See comment for CallbackParamTraits<T[n]>. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct CallbackParamTraits<T[], false> { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const T* ForwardType; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const T* StorageType; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameter traits for movable-but-not-copyable scopers. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callback<>/Bind() understands movable-but-not-copyable semantics where 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the type cannot be copied but can still have its state destructively 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// transferred (aka. moved) to another instance of the same type by calling a 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper function. When used with Bind(), this signifies transferal of the 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object's state to the target function. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For these types, the ForwardType must not be a const reference, or a 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference. A const reference is inappropriate, and would break const 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// correctness, because we are implementing a destructive move. A non-const 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference cannot be used with temporaries which means the result of a 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function or a cast would not be usable with Callback<> or Bind(). 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct CallbackParamTraits<T, true> { 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) typedef T ForwardType; 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) typedef T StorageType; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CallbackForward() is a very limited simulation of C++11's std::forward() 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used by the Callback/Bind system for a set of movable-but-not-copyable 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// types. It is needed because forwarding a movable-but-not-copyable 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argument to another function requires us to invoke the proper move 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operator to create a rvalue version of the type. The supported types are 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whitelisted below as overloads of the CallbackForward() function. The 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// default template compiles out to be a no-op. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In C++11, std::forward would replace all uses of this function. However, it 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is impossible to implement a general std::forward with C++11 due to a lack 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of rvalue references. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// simulate std::forward() and forward the result of one Callback as a 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter to another callback. This is to support Callbacks that return 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the movable-but-not-copyable types whitelisted above. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)typename enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward(T& t) { 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return t; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return t.Pass(); 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_CALLBACK_INTERNAL_H_ 179