[RFC] ini Parser

Dear, i have wrote a ini parser using range as BidirectionalRange and maybe Infinite RandomAccessRange.

*Section* class has:

* empty, front and popFront() that InputRange requires
* save() that ForwardRange requires
* opIndex() that RandomAccessRange requires
* the value of empty to be known at compile time as false

Example of use:

```d
import std.string;
import std.stdio;
import std.ini;

void main( ){
    writeln( "0 - Starting test" );
    IniFile tester = open("myConfig.ini");
    writeln( "Ini file loaded" );
    writefln( "1 - Name: %s, level: %d", tester.name, tester.level);
    writefln( "2 - childs:\n%s,", tester.childs );
    writefln( "3 - object is null: %s", tester is null );
    writefln( "4 - number of section: %d", tester.length );
    writefln( "5 - sectionA: %s", tester.get("sectionA") );
    writefln( "6 - sectionA.param1: %s", tester.get("sectionA")["param1"] );
    writefln( "7 - first section:\n%s", tester.front );
    writefln( "8 - last section:\n%s", tester.back );
    writeln(  "9 - popfront" );
    tester.popFront();
    writefln( "10 - first section:\n%s", tester.front );
    tester.popBack();
    writefln( "11 - last section:\n%s", tester.back );
    writeln(  "12 - create a section" );
    Section toAdd = new Section( "sectionD", tester.level + 1);
    writeln(  "13 - append pair key/value to this section: D = is fun" );
    toAdd["D"] = "is fun";
    writeln(  "14 - Append the newest section to main section" );
    tester.addChild( toAdd );
    writeln(  "15 - show the section added" );
    writeln( tester.get("sectionD") );
    writefln( "16 - show all childs:\n%s,", tester.childs );
    writeln(  "17 - shrink for remove unused space");
    toAdd.shrink;
    writeln(  "18 - write current section object to a file" );
    File inisavedFile = File( "soEasy.ini", "w");
    inisavedFile.write( tester );
    inisavedFile.close();
}

```


Output

```bash
$ ./test_ini
0 - Starting test
Ini file loaded
1 - Name: root, level: 0
2 - childs:
[[sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub
, [sectionB]
param3=value3
param4=value4
, [sectionC]
param5=value5
param6=value6
],
3 - object is null: false
4 - number of section: 3
5 - sectionA: [sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub

6 - sectionA.param1: value1
7 - first section:
[sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub

8 - last section:
[sectionC]
param5=value5
param6=value6

9 - popfront
10 - first section:
[sectionB]
param3=value3
param4=value4

11 - last section:
[sectionB]
param3=value3
param4=value4

12 - create a section
13 - append pair key/value to this section: D = is fun
14 - Append the newest section to main section
15 - show the section added
[sectionD]
D=is fun

16 - show all childs:
[[sectionB]
param3=value3
param4=value4
, [sectionD]
D=is fun
, null, null, null, null],
17 - shrink for remove unused space
18 - write current section object to a file

$ cat soEasy.ini 
[sectionB]
param3=value3
param4=value4
[sectionD]
D=is fun