Large sections of my codebase require full control over when and how the GC is run. The new @nogc (as well as -vgc switch) has been amazingly helpful in developing safe code I can trust wont cause the GC to run; however, there are a few aspects of D I simply have to learn to work without in these cases. One good example is WriteLn and it's cousins. To this end, I'm writing my own @nogc version of WriteLn that uses the C printf and sprintf underneath.

I'm not a coding expert by any stretch of the imagination, and I'm even less of an expert when it comes to D; for this reason, I wanted to post my implementation and get some feedback from fellow D-velopers. I'm especially interested with adhering to "phobos quality" code as much as possible, so feel free to be very picky.




enum bool isScalarOrString(T) = isScalarType!T || isSomeString!T;

@nogc void Info(Types...)(Types arguments) if ( allSatisfy!( isScalarOrString, Types ) )
{
        const uint bufferSize = Types.length * 32;
        char[bufferSize] output;
        uint index;

        try
        {
                foreach(argument; arguments)
                {       
                        static if(isIntegral!(typeof(argument))) {
                                index += sprintf(&output[index], "%i", 
argument);
                        }
                        static if(isBoolean!(typeof(argument))) {
                                if(argument) {
index += sprintf(&output[index], "%s", cast(const char*)"true");
                                }
                                else {
index += sprintf(&output[index], "%s", cast(const char*)"false");
                                }
                        }
                        static if(isFloatingPoint!(typeof(argument))) {
                                index += sprintf(&output[index], "%f", 
argument);
                        }
                        static if(isSomeChar!(typeof(argument))) {
                                index += sprintf(&output[index], "%c", 
argument);
                        }
                        static if(isSomeString!(typeof(argument))) {
index += sprintf(&output[index], "%.*s", argument.length, argument.ptr);
                        }
                }
        }
        catch(Error e)
        {
                // TODO: Better Error Handling w/ more detail
                printf("%s", cast(const char*)"An Error has occured");
        }
        catch(Exception e)
        {
                // TODO: Better Exception handling w/ more detail
                printf("%s", cast(const char*)"An Exception has occured");
        }

}

Reply via email to