<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The nonstatic members of <font face="Courier" class="">std::function</font> are declared like this:</div><div class=""><br class=""></div><div class=""><font face="Courier" class="">    typename aligned_storage<3*sizeof(void*)>::type __buf_;</font></div><div class=""><font face="Courier" class="">    __base* __f_;</font></div><div class=""><br class=""></div><div class=""><font face="Courier" class="">sizeof(std::function)</font> is apparently supposed to be 16 bytes on 32-bit systems and 32 bytes on 64-bit. On my system, it's 48 bytes, because the maximum alignment is 16 bytes, <font face="Courier" class="">__buf_</font> takes 32 bytes, and there are 8 padding bytes after the pointer.</div><div class=""><br class=""></div><div class="">As for time complexity, following a <font face="Courier" class="">__base*</font> to get to a vtable is unnecessary in the first place.</div><div class=""><br class=""></div><div class="">Here's an outline of an architecture that I think would be faster, slimmer, and better. It has better locality because calls can be dispatched without accessing the object on the heap at all. There are fewer memory accesses total. The number of indirect branches remains the same. One less pointer gets stored, FWIW.</div><div class=""><br class=""></div><div class="">It does presume that the abstract base pointer and the derived pointers are identical, but then so does the current implementation (see <font face="Courier" class="">__func::__clone(__base*)</font>). It does use C++ polymorphic classes, and I’m not sure whether that’s really kosher (see my previous message here).</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><font face="Courier" class="">template< typename ret, typename ... args ></font></div><div class=""><font face="Courier" class="">struct __base {</font></div><div class=""><font face="Courier" class="">    virtual ret call( args && ... ) = 0;</font></div><div class=""><font face="Courier" class="">    virtual void __clone(void *) const = 0;</font></div><div class=""><font face="Courier" class="">    // etc.</font></div><div class=""><font face="Courier" class="">    ~base();</font></div><div class=""><font face="Courier" class="">};</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">template< typename ret, typename ... args ></font></div><div class=""><font face="Courier" class="">struct __empty_func</font></div><div class=""><font face="Courier" class="">    : base< ret, args ... > {</font></div><div class=""><font face="Courier" class="">    virtual ret call( args && ... )</font></div><div class=""><font face="Courier" class="">        { throw bad_function_call(); }</font></div><div class=""><font face="Courier" class="">    virtual void __clone( void * p ) const</font></div><div class=""><font face="Courier" class="">        { new( p ) __empty_func; }</font></div><div class=""><font face="Courier" class="">    // etc.</font></div><div class=""><font face="Courier" class="">};</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">template< typename fp, typename alloc, typename ret, typename ... args ></font></div><div class=""><font face="Courier" class="">struct __small_func</font></div><div class=""><font face="Courier" class="">    : base< ret, args ... > {</font></div><div class=""><font face="Courier" class="">    </font><span style="font-family: Courier;" class="">__compressed_pair< </span><span style="font-family: Courier;" class="">fp, alloc > __f_;</span></div><div class=""><br class=""></div><div class=""><span style="font-family: Courier;" class="">    virtual ret call( args && ... a )</span></div><div class=""><font face="Courier" class="">        { return __f_( forward< args >( a ) ... ); }</font></div><div class=""><font face="Courier" class="">    virtual void __clone( void * p ) const</font></div><div class=""><font face="Courier" class="">        { new( p ) __small_func(__f_); } // allocator only used when assigning a new type</font></div><div class=""><font face="Courier" class="">    // (Note: Current implementation does not support allocator erasure.)</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    // etc.</font></div><div class=""><font face="Courier" class="">};</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><div class=""><font face="Courier" class="">template< typename fp, typename alloc, typename ret, typename ... args ></font></div><div class=""><font face="Courier" class="">struct __big_func</font></div><div class=""><font face="Courier" class="">    : base< ret, args ... > {</font></div><div class=""><font face="Courier" class="">    fp *__f_;</font></div><div class=""><font face="Courier" class="">    alloc __a_;</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><span style="font-family: Courier;" class="">    virtual ret call( args && ... a )</span></div><div class=""><font face="Courier" class="">        { return (*__f_)( forward< args >( a ) ... ); }</font></div><div class=""><font face="Courier" class="">    virtual void __clone( void * p ) const</font></div><div class=""><font face="Courier" class="">        { new( p ) __small_func( new fp(__f_) ); } // rather, use the allocator.</font></div><div class=""><font face="Courier" class="">    // etc.</font></div><div class=""><font face="Courier" class="">};</font></div></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">template< typename ret, typename ... args ></font></div><div class=""><font face="Courier" class="">struct function< ret( args ... ) {</font></div><div class=""><font face="Courier" class="">    aligned_storage< 4 * sizeof(void*) >::type __buf_;</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    function() {</font></div><div class=""><font face="Courier" class="">        new(__buf_) __empty_func</font><span style="font-family: Courier;" class=""><ret, args...></span><span style="font-family: Courier;" class="">;</span></div><div class=""><font face="Courier" class="">    }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    operator bool () const {</font></div><div class=""><font face="Courier" class="">        return typeid(</font><font face="Courier" class="">__empty_func<ret, args...>)</font></div><div class=""><font face="Courier" class="">            == typeid(* </font><span style="font-family: Courier;" class="">static_cast<__base</span><span style="font-family: Courier;" class=""><ret, args...></span><span style="font-family: Courier;" class="">*>(__buf_));</span></div><div class=""><font face="Courier" class="">    }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    void __clear() {</font></div><div class=""><font face="Courier" class="">        </font><span style="font-family: Courier;" class="">static_cast<__base</span><span style="font-family: Courier;" class=""><ret, args...></span><span style="font-family: Courier;" class="">*>(__buf_).~__base();</span></div><div class=""><div class=""><font face="Courier" class="">        new(__buf_) __empty_func<ret, args...>; // do this as a scope guard</font></div></div><div class=""><font face="Courier" class="">    }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    template< typename target ></font></div><div class=""><font face="Courier" class="">    enable_if_t< sizeof(__small_func<target>) <= sizeof __buf_,</font></div><div class=""><font face="Courier" class="">    function & ></font></div><div class=""><font face="Courier" class="">    operator = ( target const & o ) {</font></div><div class=""><font face="Courier" class="">        try {</font></div><div class=""><font face="Courier" class="">            new(__buf_) __small_func<target, ret, args...>( o );</font></div><div class=""><font face="Courier" class="">        } catch (...) {</font></div><div class=""><font face="Courier" class="">            __clear();</font></div><div class=""><font face="Courier" class="">            throw;</font></div><div class=""><font face="Courier" class="">        }</font></div><div class=""><font face="Courier" class="">    }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">    ~ function()</font></div><div class=""><font face="Courier" class="">        { __clear(); }</font></div><div class=""><span style="font-family: Courier;" class="">};</span></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Let me know what you think…</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Thanks,</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>David</div></body></html>