 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Markus Schaaf Guest
|
Posted: Wed Jun 01, 2005 12:30 pm Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac |
|
|
"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 >
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
|
Posted: Wed Jun 01, 2005 3:28 pm Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac |
|
|
* 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
|
Posted: Wed Jun 01, 2005 5:05 pm Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac |
|
|
"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. 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
|
Posted: Wed Jun 01, 2005 6:40 pm Post subject: Re: Literatur zu modernen statisch getypten Programmiersprac |
|
|
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 |
|
 |
|
|
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
|
|