C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Re: Literatur zu modernen statisch getypten Programmiersprac

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Markus Schaaf
Guest





PostPosted: Wed Jun 01, 2005 12:30 pm    Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac Reply with quote



"Florian Weimer" <fw (AT) deneb (DOT) enyo.de> schrieb:

Quote:
In C++ hatte ich mir mal so etwas gebastelt:

struct key_type
: enyo::persist::serializable
ENYO_TYPELIST_2(enyo::ipv4::address, std::string)
{
ENYO_PROPERTY(0, address);
ENYO_PROPERTY(1, name);
};

(Wobei ich eigentlich "enyo::ipv4::address address; std::string name;"
schreiben will, aber das geht nicht, da C++ von Haus aus keine
Introspektion kann. Implementiert wird die Introspektion stattdessen,
indem key_type von einem Tupel-Typ mit bekannter Struktur erbt.)

Dafür gibt es viele Wege. Da das Hauptanliegen immer eine knappe Syntax
ist, muß man die Bezeichner-Duplizierung automatisieren. Das geht mit
dem Präprozessor. Auf Library-Seite (der Serialisierungs-Code) erscheint
es wesentlich angenehmer, keine strukturellen Voraussetzungen von den
Datentypen zu verlangen, sondern alle Meta-Informationen in Traits-
Klassen zu halten. (Ich finde die Überlegungen zum Design von [Meta-]
Libraries in "Abrahams, Gurtovoy: C++ Template Metaprogramming" sehr
erhellend.)

Am Ende ist z.B. folgende Syntax möglich:

DEFINE_STRUCT( key_type,
(enyo::ipv4::address, address)
(std::string, name)
)

Welche vielleicht diesen Code generiert:

struct key_type {
enyo::ipv4::address address;
std::string name;
};

template<> struct ser::traits< key_type >
: boost::mpl::vector<
ser::mem< key_type, enyo::ipv4::address, &key_type::address >,
ser::mem< key_type, std::string, &key_type::name >
Quote:


Das sieht zwar alles nicht so elegant aus wie eine auf das Problem hin
entworfene Sprache, leistet jedoch das Gewünschte.

MfG

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Florian Weimer
Guest





PostPosted: Wed Jun 01, 2005 3:28 pm    Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac Reply with quote



* Markus Schaaf:

Quote:
Am Ende ist z.B. folgende Syntax möglich:

DEFINE_STRUCT( key_type,
(enyo::ipv4::address, address)
(std::string, name)
)

Welche vielleicht diesen Code generiert:

Wie muß dazu DEFINE_STRUCT aussehen? Spontan würde ich sagen, daß das
mit dem Präprozessor nicht geht.

Quote:
template<> struct ser::traits< key_type
: boost::mpl::vector
ser::mem< key_type, enyo::ipv4::address, &key_type::address >,
ser::mem< key_type, std::string, &key_type::name


Gibt's ser::mem (bzw. das Drumherum, ser::mem wird wohl wie
MemberDescriptor unten ausschauen) irgendwo zum Anschauen, evtl. in
dem von Dir erwähnten Buch?

template struct MemberDescriptor
{
typedef ClassT ClassType;
typedef MemberT MemberType;
typedef MemberT (ClassT::*MemberPointer) ;
static MemberPointer member() { return Member; }
};

Und dann zum Beispiel:

template <typename Descriptor>
inline void
assign(typename Descriptor::ClassType& c, typename Descriptor::MemberType v)
{
c.*(Descriptor::member()) = v;
}

Das ist so oder so besser als meine Tupel-Schlachten. Danke für die
Anregung.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Markus Schaaf
Guest





PostPosted: Wed Jun 01, 2005 5:05 pm    Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac Reply with quote



"Florian Weimer" <fw (AT) deneb (DOT) enyo.de> schrieb:

Quote:
* Markus Schaaf:

Am Ende ist z.B. folgende Syntax möglich:

DEFINE_STRUCT( key_type,
(enyo::ipv4::address, address)
(std::string, name)
)

Welche vielleicht diesen Code generiert:

Wie muß dazu DEFINE_STRUCT aussehen? Spontan würde ich sagen, daß das
mit dem Präprozessor nicht geht.

Das interessante Feature sind Präprozessor-Datenstrukturen (hier:
Sequenzen). Du möchtest sicher mal einen Blick auf "boost/preprocessor"
werfen. Ich muß gestehen, mit dem Präprozessor-Kram nicht so vertraut
zu sein. Ich wollte auch nur einen Hinweis darauf geben, was man alles
machen kann. (Aber ich habe die Frage natürlich erwartet. Smile Nachdem
ich nun versucht habe, etwas übersetzbares zu erzeugen, sind ein paar
kleine Korrekturen nötig. Außerdem werde ich keine Bibliothek zur
Serialisierung entwerfen.

Quote:
Gibt's ser::mem (bzw. das Drumherum, ser::mem wird wohl wie
MemberDescriptor unten ausschauen) irgendwo zum Anschauen, evtl. in
dem von Dir erwähnten Buch?

Nein. Das diente nur der Illustration. Dein Beispielcode geht in die
gedachte Richtung, wenngleich ich nicht zu viel im Vorraus abstrahieren
würde. Die angedeutete Traits-Klasse kann natürlich ausgebaut werden, um
ein komplettes Framework zur Introspektion zu erzeugen. Es geht jedoch
auch einfacher. Ich werde mich mit einer Funktion begnügen.

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/stringize.hpp>

#define DEFINE_STRUCT( name, members )
STRUCT_DEF( name, members )
STRUCT_FOR_EACH_MEM( name, members )

#define DATA_DEF( r, _, args )
BOOST_PP_TUPLE_ELEM( 2, 0, args )
BOOST_PP_TUPLE_ELEM( 2, 1, args );

#define STRUCT_DEF( name, members )
struct name { BOOST_PP_SEQ_FOR_EACH( DATA_DEF, ~, members ) };

#define APPLY_FOR_MEM( r, _, args )
f( BOOST_PP_STRINGIZE( BOOST_PP_TUPLE_ELEM( 2, 1, args ) ),
s.BOOST_PP_TUPLE_ELEM( 2, 1, args ) );

#define STRUCT_FOR_EACH_MEM( name, members )
template< typename F > void for_each_mem( name& s, F f )
{ BOOST_PP_SEQ_FOR_EACH( APPLY_FOR_MEM, ~, members ) }

Anwendung:

DEFINE_STRUCT( bsp,
(( int, i ))
(( double, d ))
)

Ergebnis (nach pretty-print):

struct bsp { int i; double d; };

template< typename F >
void for_each_mem( bsp& s, F f )
{
f( "i", s.i );
f( "d", s.d );
}

Wie man sich damit ein Serialisierungs-Framework baut, kannst Du Dir
sicher vorstellen. Wenn Du den Weg über einen Introspektions-Mechanismus
gehen willst, wirf unbedingt auch einen Blick auf "boost/mpl"! Diese
beiden Bibliotheken benötigen übrigens keinerlei Konfiguration oder
Installation (außer, einem passenden Include-Pfad).

MfG

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Bauhaus
Guest





PostPosted: Wed Jun 01, 2005 6:40 pm    Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac Reply with quote

Markus Schaaf wrote:

Quote:
In C++ hatte ich mir mal so etwas gebastelt:

Am Ende ist z.B. folgende Syntax möglich:

DEFINE_STRUCT( key_type,
(enyo::ipv4::address, address)
(std::string, name)
)



Das sieht zwar alles nicht so elegant aus wie eine auf das Problem hin
entworfene Sprache, leistet jedoch das Gewünschte.

(X'posted)

Aus Neugier, wie sähe denn damit die folgende Typ A-rein-Typ B-raus-
Prozedur aus (4 bytes rein (Typ A), ein Konditional erzeugt diese oder
jene Objekte vom Typ B (Union-artig), die dann raus geschrieben werden.):

with Interfaces;
with Ada.Streams.Stream_IO;
with Ada.Text_IO;

procedure ip_good_bad is

use Ada, Ada.Streams;
use type Interfaces.Unsigned_8;

type IPv4 is
-- simplified IP address record
record
a,b,c,d: Interfaces.Unsigned_8;
end record;

type Classified_IPv4 (good: Boolean) is
-- the discriminant part (`good`) indicates whether the `address`
-- part is good or bad
record
address: IPv4;
end record;

random_input, ip_output: Stream_IO.File_Type;

begin
Stream_IO.open(random_input, Stream_IO.In_File, "/dev/random");
Stream_IO.open(ip_output, Stream_IO.Out_File, "result.bin");

sort_them:
declare
use Stream_IO;

-- turn files into streams:
bytes: constant Stream_Access := stream(random_input);
ips: constant Stream_Access := stream(ip_output);

x: IPv4;
-- one quadruple
begin
loop
IPv4'read(bytes, x); -- 4 bytes --> one record


-- one record --> one classified record:

if x.a > 100 then
Classified_IPv4'output(ips, (good => True, address => x));

Text_IO.put('y');
else
Classified_IPv4'output(ips, (good => False, address => x));

Text_IO.put('-');
end if;

flush(ip_output);
end loop;

end sort_them;

end ip_good_bad;

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.