|
Boost : |
From: dp11229 (dpodbori_at_[hidden])
Date: 2002-01-24 15:10:31
Hi Jack,
I read your post with interest, though I am not sure what you mean by
re-entrance in the context of your system.
The issue of single base class--based hyerarchies have been
continuously discussed over the years in C++ community and some
seminal books on C++ deal with this subject in great detail (see, for
example, "Design And Evolution of C++" and "More Effective C++").
This is not the direction in which modern C++ design is evolving
(see "Modern C++ Design" by Alexandrescu)
However other languages utilize a concept similar to what you
discuss, e.g. Java, Python and (especially) Ruby. Unlike C++, these
languages are dynamically typed, have elaborate root classes and lack
the notion of templates.
Best regards,
Dmitry
--- In boost_at_y..., "jackthompson99" <JMThompson_at_E...> wrote:
> Hey guys,
>
> I sent an e-mail to Dr. Stroustrup a couple nights ago, and he
> replied, "Have a look at boost.org. They exist specifically to
> provide better libraries in the context of the C++ standard library
> and to act as a test bed for new library ideas".
>
> So, here I am. I've installed and built my boost libraries, and
I'm
> trying to figure out how to dig in.
>
> Anyway, here's what I was telling the Dr.
>
> I've been using C for about a decade, and C++ for about 7
> yrs. I'm a huge fan of your invention, and I honestly feel like
your
> name should eventually be as well known as Tesla and Edison. And
the
> Standard Template Library is an incredibly well engineered system.
I
> have a way to use it that is generic enough that it may be a
> candidate to be another standard. I know that's a lot to say. I'd
> like to explain it briefly, but first I should explain why I find
it
> useful.
>
> Since I started working with assembler, I've always felt like
> the language I was using was missing something. I've used an
> assortment of languages, and it seems like they are all missing the
> same thing. The main part isn't really missing from C++, it's just
> not commonly understood. The concept of virtual construction is
the
> core of the issue. Now I know that this problem is solved, but it
> really could stand for just one more thing to wrap it up into
> something usable for any ordinary C++ developer
.
>
> Using a virtual constructor by way of a template, a developer
> can easily create any kind of object based on any type of
identifier,
> but what good is that when the developer has exhausted all of his
> efforts on just building a simple system to dynamically create
> objects. The developer needs a way to organize these objects,
> without building another data warehouse. And I have never heard of
a
> complicated database that shouldn't be fully hierarchical. So, the
> system should be one hundred percent re-entrant.
>
> Well, I have such a beast. I'm not done with it yet. I'm
> just now finishing up a project for Textron, where some of this
> concept was cultivated into my skill set. I am having a rough time
> explaining the system to my boss, and I'm in a real bind, but
that's
> another story. The main thing that I've learned from this job is
> that the world needs to come together on one simple international
> standard for dealing with data and persistent C++ objects.
>
> I've used my ClassFactory / DataStore system as a foundation
> for another library that I call the WinFactory. This system simply
> uses the ClassFactory / DataStore as a database manager. The
objects
> held in the database are simply graphical user interface
components.
> This worked out really well, `till by boss took it apart. But I
have
> a version of it that I'm re-writing at home that is much better.
The
> database can be held either in a simple text format, resembling
> hypertext, or a binary file. The system relies heavily on the
memory
> manager, so fast memory allocation is required.
>
> I have also populated an MFC user interface with data held in
> these objects. The system seems to be able to flex with just about
> anything, and I feel like it could at least contribute to
discussions
> about new standards that are based on your standards. By the way,
I
> need to find a team that I can work with who has good work ethics
and
> integrity. Suggestions would be much appreciated.
>
>
> .....
>
>
> So, I've looked at the library list in Boost, and haven't
recognized
> anything like what I've built. I'm going to explain the system
that
> I'm going to create for Boost.org.
>
> The main concept behind the system is a warehouse environment. The
> warehouse has isles of goods. Each isle is any length, and each
isle
> contains exactly one type of product. And every product contains a
> single pointer which is initally NULL. This makes it so that when
> you pull the product off the shelf and open it, you will see
whatever
> the product is ( characters, integers, strings, etc. ), and you
will
> find one more thing. It's called the nest. Now, until you try to
> use the nest, it's empty (NULL). But when you need it, it is
> created. What is this nest you ask? It's another warehouse. Just
> like the one that it is contained within.
>
> So, the entier concept is one hundred percent re-entrant. This
makes
> it easy to build hierarchical infrastructures. The objects can be
> virtually any C++ thing. They persist with the greatest of ease to
> simple IO objects.
>
> User interfaces are easy to build with this system. Content
editors
> view it as a script. C++ programmers view the script as C++
objects.
>
> Again, I need to finish re-writing the system, and I need to
document
> it. But I feel like it is a candidate to become another Boost
> library.
>
> The main thing that is accomplished here is that I have just one
> database system that can used for every aspect of a typical
> application. Since the product of the factory is a simple C++
> object, it can, of course, hold virtually any other C++ object.
So,
> the object could be an animated button on the screen, or a phone
> number, or any other object you want.
>
> Here's the catch. All products are based on the Primitive base
> class. All Primitives are based on a root class that maintains the
> objects identification. The identification could be anything, but
> they should all be the same (mutable). And, the Primitive base
> class needs to be constructed with a reference to the Products
parent
> (the product list).
>
> The primitive base defines a few virtual functions, including
>
> The = operator lets the coder turn an entire DataStore object off
or
> on. All Products involved will be switched.
>
> Of course, you can turn on or off any node in the hierarchy
>
> The Fields() function is used to cause every data member to persist
> in storage.
> Each member gets the following function call in Fields()
> Field("ConcreteType",ConcreteType); // ConcreteType can
> be any type defined in the factory's parser and IO objects.
>
> Here is a sample:
>
> // Home.h
> class Object: public Primitive
> {
> public:
> Object(ProductList& pl) : Primitive(pl) {}
> virtual bool Fields();
> private:
> int MyInt;
> string MyString;
> vector<string> MyStringVector;
> // many more types are defined, and any developer can add on
> };
>
> Robot(Object,"Object") // I don't like macros, but this one
is worth
> it. It expands to about three lines.
>
> bool Object::Fields()
> {
> //The Primitive base defines Fields as pure virtual, so first
> derivatives can't call it. Anything based on this class should
call
> this classes Fields().
>
> // These will serialize in the proper direction based on the
> return of IsLoading()
> Field("MyInt",MyInt);
> Field("MyString",MyString);
> Field("MyStringVector",MyStringVector);
>
> return true; // false on error
> }
>
>
> Now, the data can be saved in text format or binary. Binary is
> simple. Each item is written to and read from the disk with it's
> identifier.
> The text format is simple too, approximately the same thing
happens,
> but it's formatted in a sort of hypertext style
Here is what
the
> above data could look like:
>
> <Object:MyObjectName;
> MyInt:29349;
> MyString:Some string
> with new lines.; // still ends with a semi\n. semis in
> string are parsed into #xxx;
> MyStringVector:fisrt string;
> MyStringVector:second string;
> > // end MyObjectName
>
>
> Ok, so some typical weaknesses are evident. But dealing with the
> semi is no big deal, and the redundancy in the MyStringVector names
> could be changed. But look what it gives you
.
>
> So far, no big deal. We can all write parsers. Here's the cool
> part. This object can have babies. Any type of babies. Could be
> the same type, could be different. Here's how it looks when it has
> children:
>
> <Object:MyObjectName;
> MyInt:29349;
> MyString:Some string
> with new lines.; // still ends with a semi\n. semis in
> string are parsed into #xxx;
> MyStringVector:fisrt string;
> MyStringVector:second string;
>
> <AnotherTypeOfObject:FirstBorn;
> // Might not have any data.
> > // end FirstBorn
> > // end MyObjectName
>
>
> And, if the FirstBorn has children
>
> <Object:MyObjectName;
> MyInt:29349;
> MyString:Some string
> with new lines.; // still ends with a semi\n. semis in
> string are parsed into #xxx;
> MyStringVector:fisrt string;
> MyStringVector:second string;
>
> <AnotherTypeOfObject:FirstBorn;
> // Might not have any data.
> <Object:YesAnotherObject;
> MyInt:922039;
> // leave the other fields with default values
> >
> > // end FirstBorn
> > // end MyObjectName
>
> Ok, so let's say we have this file on the disk, and we'll call it
> FamilyTree.txt. Here's the code to load it:
>
> void funk()
> {
> PathString FileName("FamilyTree.txt")
> Input in(FileName,text);
> DataStore ds;
> ds<<in;
> if (Monarch.Error()) return; // error occurred somewhere
> }
>
> and here's how it can be saved;
>
> void funk()
> {
> PathString FileName("FamilyTree.txt")
> Output out(FileName,text);
> DataStore ds;
> ds>>out;
> if (Monarch.Error()) return; // error occurred somewhere
> }
>
> Now you data store has a map<Identification,ProductList*>, and some
> methods to index and search. One very common scenario is the
coder
> knows what kind of object he is looking for in the data store. So,
> to get the stores list of type Object, do this:
> ProductList& pl=ds["Object"]; error will return an empty
> product list
>
> The Product list is a simple vector of Primitive*. If you know
that
> you are looking for MyObjectName in the list of Objects, just do
this:
> Object& o=(Object&)pl["MyObjectName"];
>
> It is important to check for errors here like this:
> if (o.Error()) {/*error handler */}
>
> if it passes that check, then the Object is safe. Otherwise o is
> actually the ErrorProduct that is safely held in the DataStore's
> Monarch.
>
>
> The DataStore and Product list are just simple map<> and vector<>
> implementations. The Factory system is no magic either. It just
has
> a list of robots, and those robots are virtual constructors. The
way
> the nest is created is by the use of a pure virtual base class that
> is defined before the Primitive. The DataStore is derived from
this
> base. This makes it so that the Primitive can call the DataStore
by
> it's pure virtuals. There are only a handful of things that ever
> need to happen in this scope. They are mainly construction,
> destruction and on/off using the assignment operator with a boolean
> parmameter.
>
> About the list boxes and treeview controls I mentioned. I have
built
> two versions so far, one for the MS Windows common controls, and
one
> for the MFC TreeView and ListView controls. They do much the same
> thing. Basically, you don't ever need to think about those
> intricacies again. This think of it as a DataStore. The tree view
> is loaded as if it is just another object, and populated with
another
> DataStore, or the same one. It's incredibly simple to use. And it
> means that all of the applications' data can be organized in one
> simple system.
>
> The average GUI is nothing more than a hierarchy of windows. Some
> are tree controls, some are buttons, some are sliders, some are
text
> windows, some are images, etc. The concept is the same:
> <Window:Main;
> <Window:SubWindow;
> <TreeView:TreeInSub;
>
> DataStorage:http://www.jackmthompson.com/menu.cfx; //
> could be anywhere. Input object needs support for every protocol
> >
> > // SubWindow
> > // Main
>
> The possibilities are endless, `cause the ClassFactory / DataStore
> system has doesn't care what type the objects are. That's what the
> Robots are for.
>
>
> So, I don't know if this is the best way to do it, but we do need
> something simple that uses ONLY C++. The parser could probably be
> faster and smaller, but the concept is rock solid.
>
> What do you think?????
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk