View mode: basic / threaded / horizontal-split · Log in · Help
September 24, 2006
Boost::Any ported to D
Hello all!

I am happy to announce that Boost::any is now ported to D Programming
Language. 

You can find sources in attachment. You can find there also original boost
file for reference.

Documentation is on boost site: http://boost.org/doc/html/any.html - with
below modifications:
1. You can not construct Any type with specific value as parameter of
constructor.
2. There is no assignment operator in D, so I used function template
function assign()

Test program attached.

After translation I have to say that D is great - source is about half size
of original and is much more understantable (I hope) <g>.

I encountered also few problems when porting from C++. Some of them are
probably bugs, some, maybe are D Language design decisions - I would be
happy to know how to threat them.

Here are they:
1. I couldn't make templatized class constructor
       this(ValueType)(ValueType v);
  It seems that it shouldn't be a problem to support such a construct in 
  language - constructor is very similar to method which can be 
  templatized.
2. Arrays with static size are not fully supported e.g. function can not
return static array. Also static arrays are not implicitly converted to
dynamic arrays, so when assigning string to Any class there is a need to
cast to dynamic array:
       (new Any).assign(cast(char[])("char[] test"));
3. I can not compile program after putting PlaceHolder interface and Holder
class into Any class (like in the original approach). Is it bug or am I
doing something wrong?
4. Why specialization for implicitly instatiated function templates is not
possible? (But it is possible to use static if and is operator).
5. It seems that compiler works different when calling it in different way -
at least on Linux.
For example below commands are not equivalent:
dmd test_any.d any.d
above command works

dmd -c -I../../ test_any.d
dmd -c any.d
gcc test_any.o any.o -o test_any -m32 -lphobos -lpthread -lm -Xlinker -ldl
above command produces error message:
test_any.o: In function
`_D5doost3any3any28__T7anyCastTC8test_any4TestZ7anyCastFC5doost3any3any3AnyZC8test_any4Test':test_any.d
(.gnu.linkonce.t_D5doost3any3any28__T7anyCastTC8test_any4TestZ7anyCastFC5doost3any3any3AnyZC8test_any4Test+0x54):
undefined reference to `_init_24TypeInfo_C8test_any4Test'
test_any.o: In function
`_D5doost3any3any27__T6HolderTC8test_any4TestZ6Holder4typeFZC8TypeInfo':test_any.d
(.gnu.linkonce.t_D5doost3any3any27__T6HolderTC8test_any4TestZ6Holder4typeFZC8TypeInfo+0x9):
undefined reference to `_init_24TypeInfo_C8test_any4Test'
collect2: ld returned 1 exit status

It seems that similar situation is when using Box from std.boxer. It is
especially painful as very good IDE Codeblocks uses this method of
compilation of D programs.

I used namespace doost (read: dust :-)) as I think it would be good idea to
put all classes translated from boost to one library. (I am also in
progress of translating boost::program_options, which will also be putted
into doost namespace).

Review of code and comments are welcomed.

-- 
Regards
Marcin Kuszczak
(Aarti_pl)
September 25, 2006
Re: Boost::Any ported to D
Just for my understanding: is this like std.boxer?

L.
September 25, 2006
Re: Boost::Any ported to D
Lionello Lunesu napisaƂ(a):
> Just for my understanding: is this like std.boxer?
> 
> L.

Yes. But without problems of std.boxer :-)

Problems with std.boxer:

1. I couldn't get information from Box type if Box is empty. There is no 
direct access to data[] property. The only way I could find is invoke on 
Box .toString method and check if returned value is "<empty string>" . 
As you see it's rather obscure.

2. I think that Any implementation is much cleaner. In std.boxer 
implementation box function gets as argument variadic number of 
parameters. Assertion is make if there is more than one parameter 
passed. And arguments type is checked on runtime...

3. Implementation of boxer seems to be much longer. boxer.d is about 29 
Kb, when any.d is just 2Kb (but without unit tests and comments - it 
will be added later)

In other hand I did not test Any with pointer types and other more 
exotic types - i will do it as i will have a little bit of free time :-)

Regards
Marcin Kuszczak
September 26, 2006
Re: Boost::Any ported to D
Marcin Kuszczak wrote:
> 
> I encountered also few problems when porting from C++. Some of them are
> probably bugs, some, maybe are D Language design decisions - I would be
> happy to know how to threat them.
> 
> Here are they:
> 1. I couldn't make templatized class constructor
>         this(ValueType)(ValueType v);
>    It seems that it shouldn't be a problem to support such a construct in 
>    language - constructor is very similar to method which can be 
>    templatized.

Indeed.

> 2. Arrays with static size are not fully supported e.g. function can not
> return static array. Also static arrays are not implicitly converted to
> dynamic arrays, so when assigning string to Any class there is a need to
> cast to dynamic array:
>         (new Any).assign(cast(char[])("char[] test"));

Static arrays are teh suck. :(
"Certain aspects of D are a pathway to many issues some consider to 
be... unnatural." :P

> 3. I can not compile program after putting PlaceHolder interface and Holder
> class into Any class (like in the original approach). Is it bug or am I
> doing something wrong?

Hum, C++ allows member(=inner) classes? Didn't know that. Are they 
static or "instance"(meaning they require an outer class context) classes?
Recall that in D they are "instance" by default, and static on option only.

> 4. Why specialization for implicitly instatiated function templates is not
> possible? (But it is possible to use static if and is operator).

What exactly did you want to do? Is it like the issue here: 
http://d.puremagic.com/issues/show_bug.cgi?id=337 ? Are the workarounds 
there acceptable?

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
September 26, 2006
Re: Boost::Any ported to D
Bruno Medeiros wrote:

> Marcin Kuszczak wrote:
>> 3. I can not compile program after putting PlaceHolder interface and
>> Holder class into Any class (like in the original approach). Is it bug or
>> am I doing something wrong?
> 
> Hum, C++ allows member(=inner) classes? Didn't know that. Are they
> static or "instance"(meaning they require an outer class context) classes?
> Recall that in D they are "instance" by default, and static on option
> only.

As I know outer class works just as namespace for inner class. So I would
say static class definitions.

> 
>> 4. Why specialization for implicitly instatiated function templates is
>> not possible? (But it is possible to use static if and is operator).
> 
> What exactly did you want to do? Is it like the issue here:
> http://d.puremagic.com/issues/show_bug.cgi?id=337 ? Are the workarounds
> there acceptable?
> 

I used workaround with static if:

Any assign(ValueType)(ValueType value) {
       static if (is(ValueType == Any)) content = value.content!=null ? 
               value.content.clone() : null;
       else content=new Holder!(ValueType)(value);
       return this;
}

but why below doesn't work?:
Any assign(ValueType)(ValueType value) {
       content=new Holder!(ValueType)(value);
       return this;
}

Any assign(ValueType : Any)(ValueType value) {
       content = value.content!=null ? value.content.clone() : null;
       return this;
}

according to documentation specialization is not permitted when using
implicit instatiation. But still don't know why...

-- 
Regards
Marcin Kuszczak
(Aarti_pl)
September 27, 2006
Re: Boost::Any ported to D
Bruno Medeiros skrev:
>> 2. Arrays with static size are not fully supported e.g. function can not
>> return static array. Also static arrays are not implicitly converted to
>> dynamic arrays, so when assigning string to Any class there is a need to
>> cast to dynamic array:
>>         (new Any).assign(cast(char[])("char[] test"));
> 
> Static arrays are teh suck. :(
> "Certain aspects of D are a pathway to many issues some consider to 
> be... unnatural." :P
> 
Perhaps a prefix is in order, in your example:
(new Any).assign(d"char[] test"); // Dynamic
(new Any).assign(s"char[] test"); // Static

And same for the new array literals (That I love).
(new Any).assign(d[1,2,3]); // Dynamic
(new Any).assign(s[1,2,3]); // Static

I guess no prefix would default to static as is?


(And before you even think about going about to complain about choosing 
'd', and 's' as prefixes have in mind: I do not care if any other 
character is used, if it is postfix instead, or whatere. It is the 
functionality I want!)


// Fredrik Olsson
September 27, 2006
Re: Boost::Any ported to D
Fredrik Olsson wrote:
> Perhaps a prefix is in order, in your example:
> (new Any).assign(d"char[] test"); // Dynamic
> (new Any).assign(s"char[] test"); // Static
> 
> And same for the new array literals (That I love).
> (new Any).assign(d[1,2,3]); // Dynamic
> (new Any).assign(s[1,2,3]); // Static
> 
> I guess no prefix would default to static as is?
> 
> 
> (And before you even think about going about to complain about choosing 
> 'd', and 's' as prefixes have in mind: I do not care if any other 
> character is used, if it is postfix instead, or whatere. It is the 
> functionality I want!)

There is already a postfix: []

"test"[] // Dynamic
"test" // Static

/Oskar
September 27, 2006
Re: Boost::Any ported to D
I was just wondering if this is still the case with D, but iirc at least 
some time ago I remember that you should use "is" keyword to test if 
object is null because "==" means opEquals.


> I used workaround with static if:
> 
> Any assign(ValueType)(ValueType value) {
>         static if (is(ValueType == Any)) content = value.content!=null ? 
>                 value.content.clone() : null;
>         else content=new Holder!(ValueType)(value);
>         return this;
> }
> 
> but why below doesn't work?:
> Any assign(ValueType)(ValueType value) {
>         content=new Holder!(ValueType)(value);
>         return this;
> }
> 
> Any assign(ValueType : Any)(ValueType value) {
>         content = value.content!=null ? value.content.clone() : null;
>         return this;
> }
> 
> according to documentation specialization is not permitted when using
> implicit instatiation. But still don't know why...
> 

static if (is(ValueType == Any)) content = value.content !is null ?
        value.content.clone() : null;                     ^----- there


Or then I have old/wrong information.
September 27, 2006
Re: Boost::Any ported to D
Oskar Linde skrev:
> Fredrik Olsson wrote:
>> Perhaps a prefix is in order, in your example:
<snip>
> There is already a postfix: []
> 
> "test"[] // Dynamic
> "test" // Static
> 

Ah, stupid of me. I like it.

But where is this documented? I can not find any mention about it under 
StringLiterals, and ArrayLiterals under expressions.


// Fredrik
September 27, 2006
Re: Boost::Any ported to D
Fredrik Olsson wrote:
> Oskar Linde skrev:
>> Fredrik Olsson wrote:
>>> Perhaps a prefix is in order, in your example:
> <snip>
>> There is already a postfix: []
>>
>> "test"[] // Dynamic
>> "test" // Static
>>
> 
> Ah, stupid of me. I like it.
> 
> But where is this documented? I can not find any mention about it under 
> StringLiterals, and ArrayLiterals under expressions.

Not very well documented, but:

http://www.digitalmars.com/d/expression.html

"""
SliceExpression:
	PostfixExpression [ ]
	PostfixExpression [ AssignExpression .. AssignExpression ]
"""

The first form is the full slice. It seems to be missing from

http://www.digitalmars.com/d/expression.html#SliceExpression

though.

/Oskar
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home