view tango/tango/core/Vararg.d @ 144:a27941d00351 trunk

[svn r149] fixed: a bunch of D-style variadics problems. fixed: GotoDefaultStatement implemented. fixed: some other minor bugs.
author lindquist
date Sat, 26 Jan 2008 17:13:22 +0100
parents 1700239cab2e
children a9dae3da4e87
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;
    }
}
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;
    }
}