view tango/tango/core/Vararg.d @ 270:d9d5d59873d8 trunk

[svn r291] Fixed a bunch of the old Phobos tests to work with Tango. Branch statements now emit a new block after it. Fixed the _adSort runtime function had a bad signature. Added a missing dot prefix on compiler generated string tables for string switch. Fixed, PTRSIZE seems like it was wrong on 64bit, now it definitely gets set properly.
author lindquist
date Mon, 16 Jun 2008 16:01:19 +0200
parents a9dae3da4e87
children
line wrap: on
line source

/**
 * The vararg module is intended to facilitate vararg manipulation in D.
 * It should be interface compatible with the C module "stdarg," and the
 * two modules may share a common implementation if possible (as is done
 * here).
 *
 * Copyright: Public Domain
 * License:   Public Domain
 * Authors:   Hauke Duden, Walter Bright
 */
module tango.core.Vararg;


version( GNU )
{
    public import std.stdarg;
}
else version( LLVMDC )
{
    /**
     * The base vararg list type.
     */
    alias void* va_list;

    /**
     * This function returns the next argument in the sequence referenced by
     * the supplied argument pointer.  The argument pointer will be adjusted
     * to point to the next arggument in the sequence.
     *
     * Params:
     *  vp  = The argument pointer.
     *
     * Returns:
     *  The next argument in the sequence.  The result is undefined if vp
     *  does not point to a valid argument.
     */
    T va_arg(T)(ref va_list vp)
    {
//         size_t size = T.sizeof > size_t.sizeof ? size_t.sizeof : T.sizeof;
//         va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) &  ~(size - 1));
//         vp = vptmp + T.sizeof;
//         return *cast(T*)vptmp;
        T* arg = cast(T*) vp;
        vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
        return *arg;
    }
}
else
{
    /**
     * The base vararg list type.
     */
    alias void* va_list;


    template va_start( T )
    {
        /**
         * This function initializes the supplied argument pointer for subsequent
         * use by va_arg and va_end.
         *
         * Params:
         *  ap      = The argument pointer to initialize.
         *  paramn  = The identifier of the rightmost parameter in the function
         *            parameter list.
         */
        void va_start( out va_list ap, inout T parmn )
        {
            ap = cast(va_list) ( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
        }
    }


    template va_arg( T )
    {
        /**
         * This function returns the next argument in the sequence referenced by
         * the supplied argument pointer.  The argument pointer will be adjusted
         * to point to the next arggument in the sequence.
         *
         * Params:
         *  ap  = The argument pointer.
         *
         * Returns:
         *  The next argument in the sequence.  The result is undefined if ap
         *  does not point to a valid argument.
         */
        T va_arg( inout va_list ap )
        {
            T arg = *cast(T*) ap;
            ap = cast(va_list) ( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
            return arg;
        }
    }


    /**
     * This function cleans up any resources allocated by va_start.  It is
     * currently a no-op and exists mostly for syntax compatibility with
     * the variadric argument functions for C.
     *
     * Params:
     *  ap  = The argument pointer.
     */
    void va_end( va_list ap )
    {

    }


    /**
     * This function copied the argument pointer src to dst.
     *
     * Params:
     *  src = The source pointer.
     *  dst = The destination pointer.
     */
    void va_copy( out va_list dst, va_list src )
    {
        dst = src;
    }
}