<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>Additional concepts: TriviallyDestructibleAfterMove and TriviallyReallocatable</title>
        <style>
            #header, .note {
                font-style: italic;
            }
        
            #title, .section {
                margin: 30px 0px;
            }
        
            #title, .section .name {
                font-weight: bold;
            }
            
            #title {
                font-size: 35px;
            }
            
            .section .name {
                font-size: 20px;
            }
            
            .draft {
                color: #999999;
            }
            
            .add {
                color: #006060;
                font-weight: bold;
            }
            
            table {
                border-collapse: collapse;
            }
            
            tr {
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <div id="header">
            Rodrigo Castro Campos, <a href="mailto:rcc.dark@gmail.com">rcc.dark@gmail.com</a>.<br>
            2008-09-30.<br>
            N2754=08-0264.
        </div>
        
        <div id="title">Additional concepts: TriviallyDestructibleAfterMove and TriviallyReallocatable</div>
        <div class="section">
            <span class="name">0. Changes since N2718</span>
            <p>
                <ul>
                    <li>Changed the implementation to be concept-based following Alisdair Meredith's recommendations and forced by a change introduced in the last
                        draft of the standard, which prohibits user specialization of standard type-traits.
                    <li>Minor grammatical fixes.
                </ul>
            </p>
        </div>
        <div class="section">
            <span class="name">I. Motivation</span>
            <p>
                Many C++ programmers (myself included) would like to have destructive move semantics. 
                Even with the current proposal we can (unsafely) say almost that:
            </p>
            <pre>
    class RAII_Handle {
    public:
        // Post-condition: h_ is valid
        RAII_Handle(const char* c)
        : h_(::open(c))
        {
            if (h_ == nullptr) {
                throw false;
            }
        }
        
        RAII_Handle(RAII_Handle&& h)
        : h_(h.h_)
        {
            h.h_ = nullptr;
        }
        
        // exposition only, not self-assignment safe
        RAII_Handle& operator=(RAII_Handle&& h)
        {
            ::close(h_);
            h_ = h.h_;
            h.h_ = nullptr;
        }
        
        // if h_ is null, calling ::close( ) may crash, must protect against it
        ~RAII_Handle( )
        {
            if (h_ != nullptr) {
                ::close(h_);
            }
        }

        // if h_ is null, calling ::execute( ) may crash
        void command(const char* c)
        {
            ::execute(h_, c);
        }
        
    private:
        RAII_Handle(const RAII_Handle&);
        RAII_Handle& operator=(const RAII_Handle&);

        Handle* h_;
    };
            </pre>
            <p>
                The constructor's postcondition is violated after a move. I should confess I thought 
                this was the way it should work before reading the move proposal completely (which states 
                that an object should be usable even after a move).
            </p>
            <p>
                This unsafe design may be fixed by adding open( ), close( ), and is_open( ) member functions. 
                However, if we want to use this kind of destructing move, the destructor must 
                always protect himself from dereferencing a null pointer.
            </p>
            <p>
                While a fully destructive move semantic would avoid this null-checking, the best solution 
                I have read (from what other programmers propose) would allow stack-RAII'ed variables to leak 
                resources; this is a -big no-. I fully agree with the current move proposal since its flexible 
                enough anyway and not unsafe (unless the programmer really wants it be). For heap or 
                placement-new'ed variables, however, the story may be different.
            </p>
            <p>
                In the example showed above a just-moved variable's destructor will have no side effects, in fact 
                it will just check if it must clean itself or not. This is true even for move-safe types; 
                many classes will have to be reimplemented (std::string in mind, with at least one character 
                as short-string optimization) so move semantics actually allow the desired performance boost. 
                The effects of their destructors inmediatly after a move could be ignored in most cases.
                This document proposes to add concepts that would allow to identify these situations.
            </p>
        </div>
        <div class="section"><span class="name">II. Impact On the Standard</span>
            <p>
                Containers that separate destruction from deallocation can use this 
                information to avoid calls to the destructors if just deallocating will suffice. This idea 
                was already explained by some (see references) and I was quite surprised not to 
                see this as part of the standard. This will give us fully-destructive-like performance without actually implementing it. 
                Implementors of containers are free to use or not this information.
            </p>
        </div>
        <div class="section"><span class="name">III. Proposed concepts and Wording</span>
            <ul>
                <li>
                    In [Concepts [utility.concepts]] add:
                    <pre class="draft">
// destruction:
auto concept HasDestructor&lt;typename T&gt; see below ;
auto concept HasVirtualDestructor&lt;typename T&gt; see below ;
auto concept NothrowDestructible&lt;typename T&gt; see below ;
concept TriviallyDestructible&lt;typename T&gt; see below ;<span class="add">
concept TriviallyDestructibleAfterMove&lt;typename T&gt; see below ;</span>

// copy and move:
auto concept MoveConstructible&lt;typename T&gt; see below ;
auto concept CopyConstructible&lt;typename T&gt; see below ;
concept TriviallyCopyConstructible&lt;typename T&gt; see below ;
auto concept MoveAssignable&lt;typename T&gt; see below ;
auto concept CopyAssignable&lt;typename T&gt; see below ;
concept TriviallyCopyAssignable&lt;typename T&gt; see below ;
auto concept HasSwap&lt;typename T, typename U&gt; see below ;
auto concept Swappable&lt;typename T&gt; see below ;<span class="add">
concept TriviallyReallocatable&lt;typename T&gt; see below ;</span>

// memory allocation:
auto concept HasPlacementNew&lt;typename T&gt; see below ;</pre>
                <li>
                    In [Destruction [concept.destruct]] add:
                    <pre class="draft">
concept TriviallyDestructible&lt;typename T&gt; : NothrowDestructible&lt;T&gt; { }
    5 Note: describes types whose destructors do not need to be executed when the object is destroyed.
    6 Requires: for every type T that is a trivial type ([basic.types]), reference, or class type with a trivial 
      destructor ([class.dtor]), a concept map TriviallyDestructible&lt;T&gt; shall be implicitly defined in 
      namespace std.
<span class="add">
concept TriviallyDestructibleAfterMove&lt;typename T&gt; : MoveConstructible&lt;T&gt; { }
    7 Note: describes types whose destructors do not need to be executed when the object is moved inmediatly 
      before being destroyed.</span></pre>
                <li>
                    In [Copy and move [concept.copymove]] add:
                    <pre class="draft">
auto concept Swappable&lt;typename T&gt; : HasSwap&lt;T&amp;, T&amp;&gt; { }
    12 Note: describes types for which two values of that type can be swapped.
void swap(T&amp; t, T&amp; u); // inherited from HasSwap&lt;T, T&gt;
    13 Postconditions: t has the value originally held by u, and u has the value originally held by t.
<span class="add">
concept TriviallyReallocatable&lt;typename T&gt; { }
    14 Note: describes types whose typical reallocation semantics (copying or moving the object to its new 
       location and then destroying the source object) are equivalent to call memcpy and not destroying 
       the source object.
    15 Requires: for every type T that is a trivial type ([basic.types]), reference, or class type with both a 
       trivial copy constructor ([class.copy]) and trivial destructor ([class.dtor]), a concept map 
       TriviallyReallocatable&lt;T&gt; shall be implicitly defined in namespace std.</span></pre>
        </div>
        <div class="section"><span class="name">IV. References</span>
            <p>
                <ul>
                    <li>Andrei Alexandrescu (2001). Generic:Typed Buffers (I). <a href="http://www.ddj.com/cpp/184403791">http://www.ddj.com/cpp/184403791</a>
                    <li>Hinnant, Howard., Dimov, Peter., Abrahams, Dave. (2002). A Proposal to Add Move Semantics Support to the C++ Language. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm</a>
                    <li>Paul Pedriana (2007). EASTL -- Electronic Arts Standard Template Library. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html#type_traits_extensions">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html#type_traits_extensions</a>
                </ul>
            </p>
            <p>
                Special thanks to Howard Hinnant and Alisdair Meredith for their feedbacks.
            </p>
        </div>
    </body>
</html>