[system] system-0.2 request for comments

system-0.2.zip has been posted in the file vault. See the "system" directory at http://boost-consulting.com/vault/ This is a major upgrade, reflecting comments and suggestions from many Boosters, but in particular Chris Kohlhoff and Peter Dimov. Important changes include: * Class error_code now supports additional categories of errors, such as those that may bubble up from asio. I'll be watching for for a response from Chris to make sure this meets asio's needs. * Refactoring into two headers, boost/system/error_code.hpp and boost/system/system_error.hpp, in line with the fine header granularity normal in Boost libraries. Docs refactored accordingly. * Addition of a header boost/identifier.hpp. For years I've used a similar class to provide the type safety and freedom from unwanted conversions that is missing when a simple int is used for an identifier. This is logically separate from the system stuff, but for convenience is included in the system package since error_code.hpp uses it. * More complete docs. * Jamfiles provided. * More extensive testing, with all tests passing for late-model GCC, CodeWarrior, Intel, and Microsoft compilers on Windows, and GCC on the Mac. Not tested yet on Linux. Comments welcome! --Beman

At 12:10 PM -0400 7/22/06, Beman Dawes wrote:
* Addition of a header boost/identifier.hpp. For years I've used a similar class to provide the type safety and freedom from unwanted conversions that is missing when a simple int is used for an identifier. This is logically separate from the system stuff, but for convenience is included in the system package since error_code.hpp uses it.
This appears to be very similar in intent to the facility provided by boost/strong_typedef.hpp, though there are significant differences in detail.

Beman Dawes wrote:
system-0.2.zip has been posted in the file vault. See the "system" directory at http://boost-consulting.com/vault/
This is a major upgrade, reflecting comments and suggestions from many Boosters, but in particular Chris Kohlhoff and Peter Dimov.
Important changes include:
The identifier is a interesting. I've got some similar code lying around. I think I might call it type_wrapper, type_generator, or something like that. identifier doesn't really communicate the purpose in my mind.
...snip details ...
* More extensive testing, with all tests passing for late-model GCC, CodeWarrior, Intel, and Microsoft compilers on Windows, and GCC on the Mac. Not tested yet on Linux.
Ok, I've tried compiling this on Linux. Couple problems. 1) Missing boost/cerrno.hpp in src/error_code.cpp #include <boost/cerrno.hpp> This file is not in the package. Commenting it out on the theory that it might have been replaced leads to: 2) Invalid char* to int conversion ~/devTools/boost_cvs/libs/system/build$ bjam ...found 225 targets... ...updating 14 targets... gcc-C++-action ../../../bin/boost/libs/system/build/libboost_system.a/gcc/debug/error_code.o ../src/error_code.cpp: In function ‘std::string<unnamed>::errno_md(const boost::system::error_code&)’: ../src/error_code.cpp:190: error: invalid conversion from ‘char*’ to ‘int’ ../src/error_code.cpp:190: error: ‘ERANGE’ was not declared in this scope ../src/error_code.cpp:197: error: ‘EINVAL’ was not declared in this scope ../src/error_code.cpp: In member function ‘int boost::system::error_code::to_errno() const’: ../src/error_code.cpp:274: error: ‘EOTHER’ was not declared in this scope ///that's the while condition here... char buf[64]; char * bp = buf; std::size_t sz = sizeof(buf); int result; while ( (result = strerror_r( ec.value(), bp, sz )) == ERANGE ) { if ( sz > sizeof(buf) ) std::free( bp ); sz *= 2; Jeff

On 7/23/06, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
Beman Dawes wrote:
system-0.2.zip has been posted in the file vault. See the "system" directory at http://boost-consulting.com/vault/
This is a major upgrade, reflecting comments and suggestions from many Boosters, but in particular Chris Kohlhoff and Peter Dimov.
Important changes include:
The identifier is a interesting. I've got some similar code lying around. I think I might call it type_wrapper, type_generator, or something like that. identifier doesn't really communicate the purpose in my mind.
It isn't a general type_wrapper or type_generator, so maybe identifier_type or identifier_base? I'm not wedded to the "identifier" name if anyone has further name suggestions. But "identifier" does seem appropriate.
...snip details ...
* More extensive testing, with all tests passing for late-model GCC, CodeWarrior, Intel, and Microsoft compilers on Windows, and GCC on the Mac. Not tested yet on Linux.
Ok, I've tried compiling this on Linux. Couple problems.
1) Missing boost/cerrno.hpp in src/error_code.cpp
#include <boost/cerrno.hpp>
This file is not in the package...
Oops! Sorry. I've updated the zip file. Thanks, --Beman

On Sun, 23 Jul 2006 09:26:55 -0700, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
The identifier is a interesting.
It's much more than that! I did run and see it (proud to be the first downloader of version 0.2.1 :-)) and I'm enthusiastic. Too many times I've realized I needed something to stem the pervasive danger of Win32's all-is-a-dword typedefs and postponed the issue. This is one of those lovely pearl which combine elegance and usefulness in a way which happens to be obvious only once you have seen it. That's the Euclid algorithm of the type system! :-) About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"? -- [ Gennaro Prota, C++ developer for hire ]

Gennaro Prota wrote:
On Sun, 23 Jul 2006 09:26:55 -0700, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
The identifier is a interesting.
It's much more than that! I did run and see it (proud to be the first downloader of version 0.2.1 :-)) and I'm enthusiastic. Too many times I've realized I needed something to stem the pervasive danger of Win32's all-is-a-dword typedefs and postponed the issue.
Don't get me started ;-)
This is one of those lovely pearl which combine elegance and usefulness in a way which happens to be obvious only once you have seen it. That's the Euclid algorithm of the type system! :-)
Well, it's handy, but it's only part of the story. One might argue that this utility could be combined with other 'value-type' programming tools like Boost.Enum (although I don't really care that much for some of the details of the current proposal) and constrained_value. These are small utilities that allow the quick generation of valuetypes that clarify interfaces and prevent errors.
About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"?
I guess my issue is that identifier normally means the name of a type instance....so that's a point of confusion for me at least. Jeff

"Jeff Garland" <jeff@crystalclearsoftware.com> wrote in message news:44C3FB5B.8010604@crystalclearsoftware.com...
Gennaro Prota wrote:
About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"?
I guess my issue is that identifier normally means the name of a type instance....so that's a point of confusion for me at least.
I think of identifier mostly in database terms. For example, in the geographic applications I do, there are types CountryId, PostalCodeId, StateId, CountyId, LocalityId, NeighborhoodId, StreetId, StreetNameId, etc, etc. It is very easy to mix them up, so having separate types lets the compiler detect these mixups. That isn't to say a better name can't be found. I just haven't heard one yet that I like better. --Beman

Beman Dawes wrote:
"Jeff Garland" <jeff@crystalclearsoftware.com> wrote in message news:44C3FB5B.8010604@crystalclearsoftware.com...
Gennaro Prota wrote:
About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"? I guess my issue is that identifier normally means the name of a type instance....so that's a point of confusion for me at least.
I think of identifier mostly in database terms. For example, in the geographic applications I do, there are types CountryId, PostalCodeId, StateId, CountyId, LocalityId, NeighborhoodId, StreetId, StreetNameId, etc, etc. It is very easy to mix them up, so having separate types lets the compiler detect these mixups.
That isn't to say a better name can't be found. I just haven't heard one yet that I like better.
In the database domain I tend to use "key" mostly because of the loaded, and equivalent, meaning it has in the relation (SQL) realm. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - grafikrobot/yahoo

"Gennaro Prota" <gennaro_prota@yahoo.com> wrote in message news:0or7c2tvb3ij78bhn127liokq07q9l1c6e@4ax.com...
On Sun, 23 Jul 2006 09:26:55 -0700, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
The identifier is a interesting.
It's much more than that! I did run and see it (proud to be the first downloader of version 0.2.1 :-)) and I'm enthusiastic. Too many times I've realized I needed something to stem the pervasive danger of Win32's all-is-a-dword typedefs and postponed the issue.
This is one of those lovely pearl which combine elegance and usefulness in a way which happens to be obvious only once you have seen it. That's the Euclid algorithm of the type system! :-)
Thanks for the kind words!
About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"?
Yes. Take a look at the Wikipedia article on third normal form at http://en.wikipedia.org/wiki/Third_normal_form In the example, I call "part number" an identifier. It is a number assigned to parts to uniquely identify them. It is common for an identifier to serve no other purpose and its value be immaterial. So it is pretty close to what the database folks call a key. But the value of keys is often material, as in the manufacturer table in the Wikipedia article. --Beman

On Mon, 24 Jul 2006 20:55:39 -0400, "Beman Dawes" <bdawes@acm.org> wrote:
That's the Euclid algorithm of the type system! :-)
Thanks for the kind words!
They were due :-) Award for merit. (Just to clarify why I'm so enthusiast: we have all kinds of marvelous solutions here in boost, so why am I impressed by such a "simple" thing? Well, it's my belief that complex infrastructures are often result of education; simplicity is the result of genius --this is IMHO illustrative: looks like Gauss was a little rogue when he was in primary school, so the teacher, to keep him quiet for, supposedly, a long while, assigned him the task to sum up all integers from 1 to 100: he took the pen, observed that if you take the last and the first number and sum them you get 101, and the same goes if you move inwards by taking them in pairs (2+99, 3+98, etc.) --since there were obviously 50 pairs he immediately submitted the result: 50*101=5050. That's genius :-))
About the name, isn't "identifier" meant as "something which gives an identity" rather than as "C++ grammar identifier"?
Yes. Take a look at the Wikipedia article on third normal form at http://en.wikipedia.org/wiki/Third_normal_form
In the example, I call "part number" an identifier. It is a number assigned to parts to uniquely identify them. It is common for an identifier to serve no other purpose and its value be immaterial. So it is pretty close to what the database folks call a key. But the value of keys is often material, as in the manufacturer table in the Wikipedia article.
Yeah, pretty clear. I wouldn't like this to shift into the classical Parkinson's bicycle shed, so I'll just have a short try: "identifier" is IMHO a good name except for the fact that it is immediately associated by C++ programmers with its grammar meaning, as Jeff noticed. The term I've most frequently heard for the database-related concept is "id", which is of course short for "identifier" but doesn't have the drawback above. OTOH it's probably a bit too short for library usage. Alternatively, I can see "newtype", "strong_type", "strong_typed" or "identified"(!?). Given that the context of usage is a derived class definition I have a slight preference for the first and the third one, though I don't object to the current name either. Hope this makes sense :-s -- [ Gennaro Prota, C++ developer for hire ]

In message <hnubc2hoe0ok5pjem2hfia6ejdhile71cc@4ax.com>, Gennaro Prota <gennaro_prota@yahoo.com> writes
On Mon, 24 Jul 2006 20:55:39 -0400, "Beman Dawes" <bdawes@acm.org> wrote:
...
In the example, I call "part number" an identifier. It is a number assigned to parts to uniquely identify them. It is common for an identifier to serve no other purpose and its value be immaterial. So it is pretty close to what the database folks call a key. But the value of keys is often material, as in the manufacturer table in the Wikipedia article.
Yeah, pretty clear. I wouldn't like this to shift into the classical Parkinson's bicycle shed, so I'll just have a short try: "identifier" is IMHO a good name except for the fact that it is immediately associated by C++ programmers with its grammar meaning, as Jeff noticed. The term I've most frequently heard for the database-related concept is "id", which is of course short for "identifier" but doesn't have the drawback above. OTOH it's probably a bit too short for library usage. Alternatively, I can see "newtype", "strong_type", "strong_typed" or "identified"(!?). Given that the context of usage is a derived class definition I have a slight preference for the first and the third one, though I don't object to the current name either.
The term Object ID, or OID, seems to be common in some circles. Drawbacks in this context tho' are that it does not necessarily correspond to a data member('s value); and there might be more than one data member whose value would uniquely identify the object. -- Alec Ross

On 7/22/06, Beman Dawes <bdawes@acm.org> wrote:
system-0.2.zip has been posted in the file vault. See the "system" directory at http://boost-consulting.com/vault/
These html files can be viewed directly: http://mysite.verizon.net/~beman/identifier.html http://mysite.verizon.net/~beman/error_code.html http://mysite.verizon.net/~beman/system_error.html http://mysite.verizon.net/~beman/endian.html Note that only the html files are present, so the links to headers will not work. --Beman

Beman wrote:
* Addition of a header boost/identifier.hpp. For years I've used a similar class to provide the type safety and freedom from unwanted conversions that is missing when a simple int is used for an identifier. This is logically separate from the system stuff, but for convenience is included in the system package since error_code.hpp uses it.
I like the idea of having such a (meta) construct in my programming portfolio, much like the "newtype" in Haskell, which introduces an isomorphic type. A few comments: 1. You are right in that it is separate, and should definitely be separate from the error code stuff; actually, since it is a construct mapping types to types - i.e., a meta function - it might even find its proper home in MPL :-) 2. As someone else pointed out, even though this functor establishing homorphic types is useful for the use case of having identifiers, it should not stop there. Thus, its name should reflect that wider scope, such as "homorphic_type." Ok, more pragmatic then: "embed_type." [hope that going from a adjective to a verb did not tick anyone off] 3. I see a few distinct types of homomorphisms here, which should correspond to policies: (i) order (ii) equivalence (iii) assignability (iv) conversion (to source) I implemented them as individual policy links that are then chained together explicitly. Will use a hierarchy generator, such as Loki's, or create a chaining construct with the help of MPL and upload it to the vault. I could not access the file vault, but will upload it later. Till then, I attach the header in the bottom of this file. First, a tiny sample where one can play with the policy flags a bit - such as turning off conversion. /* File: test_embed_type.hpp Author: David Bergman Date: 2006-07-25 This is a simple test of the 'embed_type' proposal, which is actually just a slightly decoupled (policy-wise) and more generic version of Beman Daves' "identifier" proposal. */ #include <iostream> #include <boost/embed_type.hpp> // We include Beam Daves' identifier here as a special case template <typename T, D> class identifier : public boost::embed_type<int, CustomerId, true, // preserve order true, // preserve equivalence false, // cannot assign from embedded type false // cannot convert to embedded type > {}; class CustomerId : public boost::embed_type<int, CustomerId, true, // order true, // equivalence true, // assignability true // conversion to embedded > { public: CustomerId() {} // Ugh, GCC does not support mentioning only the template // name for sub classes :-(, so we use assignment instead... CustomerId(int num) { value_ref(num); } }; int main(int argc, const char* argv[]) { CustomerId id = 42; int idNum = id; std::cout << "Id is CustomerId(" << id << ") or int(" << idNum << ")" << std::endl; } Ok, now the header itself (yes, I should include proper copyright markers etc.) #ifndef EMBED_TYPE_HPP #define EMBED_TYPE_HPP namespace boost { /* File: embed_type.hpp Author: David Bergman, based on Beman Daves' 'identifier' proposal. Date: 2006-07-25 These templates and classes embed a (primitive or not) type, and with a set of policies decides what aspects of that type should be exposed in the embedding. TODO: use MPL (or similar meta techniques) to build the chain of policies in compile-time. NOTE TO MYSELF: implement such a hierarchy generator using MPL. */ /* The various policies that we use in the final embedding. The policies are either implemented or not, depending on a template flag. They constitute an inheritance chain of types. We could generate a hierarchy with a meta generator such as Loki's GenScatterHierarchy, also allowing for totally new embedding aspects, instead of this explicit chaining of enabled of disabled policies. The template parameter D signifies the embedding type while the C parameter is the current bottom of chain. */ // Order template <typename T, typename D, bool implement, typename C> class embed_order : public C { public: // The "this->" is needed since GCC 3.4 (and the C++ standard...) will // not find the names from the template parameters bool operator<(const D& rhs) const { return this->value_ref() < rhs.value_ref(); } bool operator<=(const D& rhs) const { return this->value_ref() <= rhs.value_ref(); } bool operator>(const D& rhs) const { return this->value_ref() > rhs.value_ref(); } bool operator>=(const D& rhs) const { return this->value_ref() >= rhs.value_ref(); } }; template <typename T, typename D, typename C> class embed_order<T, D, false, C> : public C {}; // Equivalence template <typename T, typename D, bool implement, typename C> class embed_equivalence : public C { public: bool operator==(const D& rhs) const { return this->value_ref() == rhs.value_ref(); } bool operator!=(const D& rhs) const { return this->value_ref() != rhs.value_ref(); } }; template <typename T, typename D, typename C> class embed_equivalence<T, D, false, C> : public C {}; // Assignability template <typename T, typename D, bool implement, typename C> class embed_assignability : public C { public: D& operator=(const D& rhs) { this->value_ref(rhs.value_ref()); return *this; } }; template <typename T, typename D, typename C> class embed_assignability<T, D, false, C> : public C {}; // Conversion to source template <typename T, typename D, bool implement, typename C> class embed_conversion : public C { public: operator T() const { return this->value_ref(); } }; template <typename T, typename D, typename C> class embed_conversion<T, D, false, C> : public C {}; /* The structure-holding type */ template <typename T> class embed_structure { protected: embed_structure() {}; embed_structure(T m_value) : m_value(m_value) {} public: T value() const { return m_value; } protected: void value_ref(const T& value) { m_value = value; } T& value_ref() { return m_value; } const T& value_ref() const { return m_value; } private: T m_value; }; /* The (conglomerate) embedding itself. Painfully linking the type chain... */ template<typename T, typename D, bool embedOrder = true, bool embedEquivalence = true, bool embedAssignability = true, bool embedConversion = true > class embed_type : public embed_order<T, D, embedOrder, embed_equivalence<T, D, embedEquivalence, embed_assignability<T, D, embedAssignability, embed_conversion<T, D, embedConversion, embed_structure<T> > > > > { protected: embed_type() {} embed_type(T value) : embed_structure<T>(value) {}; }; } // namespace boost #endif

On Sun, 23 Jul 2006 20:15:57 -0400, "David Bergman" <davidb@home.se> wrote:
I like the idea of having such a (meta) construct in my programming portfolio, much like the "newtype" in Haskell
Not a bad name, though maybe a bit generic :-)
Thus, its name should reflect that wider scope, such as "homorphic_type."
This begins to put more stress on operation and relation preserving. And with the _type suffix it suggests a typedef in existing C++ practice. -- [ Gennaro Prota, C++ developer for hire ]

I have a new version of my counter-proposal (or suggestion, I just want to take FULL advantage of the power in his idea...) to Beman's 'identifier' notion. My proposal was a more generic 'embed_type' with various policies. The old version (a few hours old now...) used a set of fixed flags in order to enable or disable certain homomorphisms. The new version handles that much better, via a vector of policy types. I also have a (somewhat associated) proposal - that I just created - to create a hierarchy from a vector of types. Actually, two different kinds of hierarchies: 1. A spine-like hierarchy, where the types are attached as maximal elements. struct A { void a() {} }; struct B { void b() {} }; struct AB : generate_spine<mpl::vector<A, B> > {}; AB ab; ab.a(); ab.b(); 2. A chain, where the types have "holes" template<class Base> struct A : Base { void a() { b(); }; struct B : Base { void b() {}; struct AB : generate_chain<mpl::vector<quote_raw3<A>, quote_raw3<B>
{};
I have gathered those two proposals in files 'embed_type.hpp' and 'generate_hierarchy.hpp', which I will upload as soon as I get access to the vault. Till then, I talk about the hierarchy generation here: http://davber.blogspot.com/2006/07/hierarchy-generation-in-c.html. Back to the 'embed_type' proposal, an example - which happens to be Beman's 'identifier' looks like: template <typename T, typename D> struct identifier : embed_type<T, D, mpl::vector<policy<embed_order>, policy<embed_equivalence> > > {}; A more concrete example (yes, I know it will fail on GCC 3.4, due to the base class being mentioned in the constructor without the type parameters; ugh...): class CustomerId : public embed_type<int, CustomerId, mpl::remove<embed_policies_isomorphism, policy<embed_conversion> >::type> { CustomerId(int num) : embed_type(num) {} } CustomerId id = 42; int idNum = id; // Will fail, since we removed the conversion policy! In this case we preserved all operations minus conversion to int, which we explicitly removed from the type vector. /David

"David Bergman" <davidb@home.se> wrote in message news:005301c6aeb6$576d2750$a0da1105@davidtp...
Beman wrote:
* Addition of a header boost/identifier.hpp. For years I've used a similar class to provide the type safety and freedom from unwanted conversions that is missing when a simple int is used for an identifier. This is logically separate from the system stuff, but for convenience is included in the system package since error_code.hpp uses it.
I like the idea of having such a (meta) construct in my programming portfolio, much like the "newtype" in Haskell, which introduces an isomorphic type.
A few comments:
1. You are right in that it is separate, and should definitely be separate from the error code stuff; actually, since it is a construct mapping types to types - i.e., a meta function - it might even find its proper home in MPL :-)
Yes - I just included it with the error code stuff because it was needed there, and I wanted to see if there was any interest in it as a separate submission.
2. As someone else pointed out, even though this functor establishing homorphic types is useful for the use case of having identifiers, it should not stop there. Thus, its name should reflect that wider scope, such as "homorphic_type." Ok, more pragmatic then: "embed_type." [hope that going from a adjective to a verb did not tick anyone off]
3. I see a few distinct types of homomorphisms here, which should correspond to policies: (i) order (ii) equivalence (iii) assignability (iv) conversion (to source)
I implemented them as individual policy links that are then chained together explicitly. Will use a hierarchy generator, such as Loki's, or create a chaining construct with the help of MPL and upload it to the vault.
I toyed with the idea of either a policy-base or generative-programming approach, and decided they would add a lot of complexity for very little gain when compared to just telling the user to code the members, which are very simple, when needed. Simplicty has its virtues. That said, I encourage you to keep refining your ideas. You may be able to craft a homomorphic type generater that has enough benefits to be compelling. --Beman

Hi Beman Beman Dawes <bdawes@acm.org> wrote:
* Class error_code now supports additional categories of errors, such as those that may bubble up from asio. I'll be watching for for a response from Chris to make sure this meets asio's needs.
Looks good! I have just uploaded a version of asio that has been modified to use error_code and system_error where appropriate. It's in the vault, in the System directory. Just a few minor things: - the system_error::what() function is defined in system_error.hpp without being inline, causing multiple definition linker errors. - I'm not sure about the category names errno_ec and native_ec, since I keep reading the "ec" as error_code. I don't have any good suggestions, except perhaps more verbose names likes errno_category and native_error_category. - The Jamfile is doing something strange when I try to link the boost_system library from the asio unit test Jamfile, but it works fine when used from non-test Jamfiles. - The boost::identifier iostream operators aren't always working correctly with VC8. For example, try compiling the asio serialization example, which gives errors saying operator>> is ambiguous. - error_code::new_category probably needs to be made thread-safe, or the limitations on when it can be called should be documented. - You might want to add special handling when converting the success errno (i.e. 0) to a string on POSIX. The strerror function doesn't give you a string for it, so you end up with "EINVAL", which is a bit surprising. Converting asio to use this stuff was a non-trivial exercise, so I can confidently say I now have extensive experience using these classes ;) I'm happy with the interface -- it's clean and easy to use, particularly when it comes to defining new error categories. Cheers, Chris

On Mon, 24 Jul 2006 06:34:06 -0700 (PDT), Christopher Kohlhoff <chris@kohlhoff.com> wrote:
Hi Beman
Beman Dawes <bdawes@acm.org> wrote:
* Class error_code now supports additional categories of errors, such as those that may bubble up from asio. I'll be watching for for a response from Chris to make sure this meets asio's needs.
Looks good! I have just uploaded a version of asio that has been modified to use error_code and system_error where appropriate. It's in the vault, in the System directory.
Hi Chris, long time I wanted to ask this: why do we use the vault rather than the boost sandbox? Wouldn't the latter make our lives much easier? After all, once a library is finalized we could even delete it from there, if pollution is a problem, but at least we would have a clear view of the changes and a straightforward way to get the latest version without having to remember that a new one was announced on the list :-) -- [ Gennaro Prota, C++ developer for hire ]

Hi Gennaro, Gennaro Prota <gennaro_prota@yahoo.com> wrote:
long time I wanted to ask this: why do we use the vault rather than the boost sandbox? Wouldn't the latter make our lives much easier?
Do you mean the sandbox CVS? I think the vault is more appropriate for stuff that's mentioned in mailing list discussion. It is usually simpler to download a single package using a web browser than to check out something from CVS, and not all readers may have access to CVS or the ability to check out from repositories not on their own network. Also if you check out of CVS you won't get documentation that's normally prebuilt into a download package.
After all, once a library is finalized we could even delete it from there, if pollution is a problem, but at least we would have a clear view of the changes and a straightforward way to get the latest version without having to remember that a new one was announced on the list :-)
Maybe there's another solution that meets the requirements of libraries that aren't yet in an official boost release? A page on www.boost.org that links to the latest download packages for the in-development libraries, perhaps? Cheers, Chris

"Christopher Kohlhoff" <chris@kohlhoff.com> wrote in message news:20060724133406.3655.qmail@web32610.mail.mud.yahoo.com...
Hi Beman
Beman Dawes <bdawes@acm.org> wrote:
* Class error_code now supports additional categories of errors, such as those that may bubble up from asio. I'll be watching for for a response from Chris to make sure this meets asio's needs.
Looks good! I have just uploaded a version of asio that has been modified to use error_code and system_error where appropriate. It's in the vault, in the System directory.
Just a few minor things:
- the system_error::what() function is defined in system_error.hpp without being inline, causing multiple definition linker errors.
Nuts! That's about the millionth time I've made that mistake. Will fix.
- I'm not sure about the category names errno_ec and native_ec, since I keep reading the "ec" as error_code. I don't have any good suggestions, except perhaps more verbose names likes errno_category and native_error_category.
I started out with errno_category and native_error_category (or something similar), but found them overly verbose in some real code I converted.
- The Jamfile is doing something strange when I try to link the boost_system library from the asio unit test Jamfile, but it works fine when used from non-test Jamfiles.
Hum.... Not sure what to make of that. What error are you getting?
- The boost::identifier iostream operators aren't always working correctly with VC8. For example, try compiling the asio serialization example, which gives errors saying operator>> is ambiguous.
They aren't that critical, so could be removed if necessary. Perhaps some enable_if expert could take a look and see how to make them less likely to cause ambiguities.
- error_code::new_category probably needs to be made thread-safe, or the limitations on when it can be called should be documented.
Do we have a portable way to make it thread safe?
- You might want to add special handling when converting the success errno (i.e. 0) to a string on POSIX. The strerror function doesn't give you a string for it, so you end up with "EINVAL", which is a bit surprising.
To say the least. I'll add some special handling. Good catch!
Converting asio to use this stuff was a non-trivial exercise, so I can confidently say I now have extensive experience using these classes ;) I'm happy with the interface -- it's clean and easy to use, particularly when it comes to defining new error categories.
Good, it makes me really happy to hear you say that:-) I was worried that I might be so deep in the forest I could only see the trees. Thanks for the report, --Beman

Hi Beman, Beman Dawes <bdawes@acm.org> wrote:
"Christopher Kohlhoff" <chris@kohlhoff.com> wrote in message
- The Jamfile is doing something strange when I try to link the boost_system library from the asio unit test Jamfile, but it works fine when used from non-test Jamfiles.
Hum.... Not sure what to make of that. What error are you getting?
After a bit more investigation I think it isn't to do with the system library at all. Nothing for you to worry about :) It's apparently due to the 'link' rule from testing.jam not passing the libraries to the linker. It works fine if I change it to use the 'run' rule instead. The problem only shows up now because the system library is the first non-header-file-only library used in those particular unit tests.
- error_code::new_category probably needs to be made thread-safe, or the limitations on when it can be called should be documented.
Do we have a portable way to make it thread safe?
Since we want to avoid the nasty problems that come from the order of initialisation of globals across translation units, the best I can think of is: - On POSIX, use a static pthread_mutex_t initialised with PTHREAD_MUTEX_INITIALIZER. - On Windows, use a named mutex (with the name derived from the process ID) or a handcrafted spinlock using a static long variable. Cheers, Chris

On Sat, 22 Jul 2006 12:10:21 -0400, Beman Dawes <bdawes@acm.org> wrote:
system-0.2.zip has been posted in the file vault. See the "system" directory at http://boost-consulting.com/vault/
This is a major upgrade, reflecting comments and suggestions from many Boosters, but in particular Chris Kohlhoff and Peter Dimov.
First of all I'd like to thank you for your careful work on this library. I see it constantly and quickly improving in design and usefulness. And I believe we are very near to the final version. The only major flow I can see concerns i18n. Here are my comments (I'm deliberately excluding optimization, particularly of lookup in the native_to_errno[] array, and other implementation details): * Microsoft CRT/SCL-secure warnings: to be transparent to users I guess we would better #pragma push/pragma pop around disable-C4996. * The usage of L'\n', L'\r' etc. doesn't give the desired effect (unless the effect I desire is incorrect :-)). Similarly for functions having string and wstring variations. That's an issue I faced for dynamic_bitset<> with the help of James Kanze; and what I've learned from him is basically the reason why I suggested not to use strings everywhere a const char* is accepted now in the standard. Sticking to the point: a) the conversion of the character literals and string literals depends on the compile-time locale; for the run-time locale you need a facet, and that's why one should use streams, not strings. After all, the implementation of std::endl is an example: os.put(L\n); os.flush(); // not this way b) there's no guarantee that operator== can be used on a generic char type (and no guarantee that one can construct a CharT from a char). The only viable char->CharT paths are ctype::widen and codecvt::in. For comparison there's Traits::eq() c) no way to spell a "generic character literal", except for the null character, which is guaranteed to be CharT() for any character type * Though you took care to not let escape exceptions from the what() function, that doesn't remove the root problem: having a string subobject in system_error objects, which can make its construction fail directly at the throw site. That would end up reporting a different exception (coming from std::string) than system_error. * Did you consider using virtual inheritance, as advised in more/error_handling.html? * [very minor] you don't need #include <iosfwd> in identifier.hpp, do you? As far as I can see the implementation puts constraints on the right hand operand of << and >>, not on the left hand one, which may well not be a stream. That's all, I think :-) Please, don't beat me! -- [ Gennaro Prota, C++ developer for hire ]

Hi, I'm taking this out of the other thread indicated in the subject line, so that it can probably get more attention.
* Microsoft CRT/SCL-secure warnings: to be transparent to users I guess we would better #pragma push/pragma pop around disable-C4996.
I'd ask if we can solve this at the config level. Currently every library seems to do on its own, which doesn't look good. At a cursory inspection at least the following source files disable the warning for themselves: boost/date_time/c_time.hpp boost/interprocess/detail/config_begin.hpp boost/test/detail/enable_warnings.hpp boost/test/detail/suppress_warnings.hpp Serialization seems to do it in its jam file: boost/libs/serialization/build/serialization.jam and boost/tools/jam/src/build.jam also has a /wd4996 for both debug and release targets. It appears we should handle it more consistently. -- [ Gennaro Prota, C++ developer for hire ]
participants (8)
-
Alec Ross
-
Beman Dawes
-
Christopher Kohlhoff
-
David Bergman
-
Gennaro Prota
-
Jeff Garland
-
Kim Barrett
-
Rene Rivera