Re: [boost] Re: Re: Re: Re: GUI/GDI template library

2003-08-03 Thread Terje Slettebø
>From: "Philippe A. Bouchard" <[EMAIL PROTECTED]>

> WxWindows don't have any intermediate compiler but the end user syntax is
> not attractive for the signal / slot mechanism (macros).

It's also possible to do the signal/slot without macros on wxWindows. See
here (http://www.wxwindows.org/hworld2.txt) for an example. It's all done in
standard C++, without any macros.

The syntax is similar to Qt's signal/slot mechanism, but without any
preprocessor/intermediate compiler (MOC) needed.

Here's a version using macros, which then resembles MFC
(http://www.wxwindows.org/hworld.txt).

Naturally, one might use Boost.Signals for a boostified version.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Re: GUI/GDI template library

2003-08-03 Thread Terje Slettebø
>From: "Rob & Lori" <[EMAIL PROTECTED]>

> E. Gladyshev wrote:
>
> >--- Edward Diener <[EMAIL PROTECTED]> wrote:
> >
> >>As you have pointed out in the rest of your post, it
> >>may prove more
> >>worthwhile to work with the developers which already
> >>exist for a free
> >>cross-platform framework like wxWindows, in order to
> >>encourage them to use
> >>more modern C++ idioms
> >
> >I agree with this suggestion.  I am wondering how
> >realistic would it be?

As I quoted from their roadmap, there are plans to do this - at least
changing the components used to standard components, such as changing
wxString to std::sstring. After all, the library originated long before
there was a standard, and a standard string.

> Personally I'm not certain I like that idea.  WxWindows is much more
> than just multi-platform GUI.  This means when you only need the GUI
> you'll be linking to everything else in their library, which increases
> your code size.

I'm aware of that. However, with boostification/transforming it to use
modern C++ idioms, one might also change it to use existing standard
components for these, or Boost components.

One might also omit parts not strictly belonging to a GUI library, such as
database access. Or one could include it, if no Boost library supports that
at the time.

Make no mistake - this is a lot of work, too. However, it may be much less
work than creating one from scratch. What do we want - vaporware of a Boost
GUI library coming "real soon now", perhaps not appearing for many years, if
ever, due to the amount of work, or adapting an existing solution and being
able to use it here and now, with a boostified version to come?

Anyway, it was just a thought. wxWindows is already tested and debugged -
and has been used in real-world projects. It's shown its worth.

By the way, dynamic layout have been mentioned (like layout managers in
Java), and wxWindows support these, as well.

As Alec Ross pointed out, there's also an XML-based portable resource format
(XRC) (http://www.wxwindows.org/manuals/2.4.0/wx478.htm), and a resource
editor for it.

> Besides, I believe it would take more effort to change all the existing
> WxWindows code to use modern C++ techniques (which they would probably
> be against for backwards compatibility reasons) than it would to create
> one from scratch.

This might also be. It is something to consider. My goal was to include
existing libraries in the discussion, and that has been met.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Re: GUI/GDI template library

2003-08-03 Thread Terje Slettebø
>From: "Edward Diener" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >> From: "Edward Diener" <[EMAIL PROTECTED]>
> >
> >> Add to this the fact that nearly every C++ programmer already works
> >> with a framework library depending on his implementation of choice.
> >> On Windows alone I know of WTL, ATL, MFC, OWL, VCL, wxWindows, QT,
> >> and no doubt
> > others
> >> about which I have no knowledde, each tied very closely to a
> >> particular
> > C++
> >> compiler, IDE, and implementation.
> >
> > I just wanted to point out that several of these, Qt and wxWindows,
> > are cross-platform, so they are not tied to any specific compiler or
> > platform. wxWindows is also Open Source, and I've good experience
> > with the little I've used it. It's very easy to get up and running
> > with it (at least it was on Windows). snipped...
>
> I see you are supporting my main point which was that re-inventing a GUI
> framework for Boost, with both many platform dependent and cross-platform
> frameworks already in place and very popular with most C++ programmers,
will
> be duplicating functionality which already exists. I do realize that most
of
> these frameworks do not use template techniques but that doesn't make them
> necessarily any less popular with their many users. Also, as I pointed
out,
> the amount of work necessary to implement an effective GUI framework is
> enormous, given the differences in GUI controls and GDI-like functionality
> on the major OSs.

I complately agree. That was also an unspoken point of my posting - that
there's an enourmous amount of work to do this. Just wrapping/emulating
_one_ platform is a lot of work. I've been working on a Windows/Direct3D
wrapper, myself, which wraps the Win32 API, and especially due to the
low-level nature of this API, it's a lot of work to do so. Since I
discovered wxWindows, I've preferred to use that, instead, than duplicating
all the work that has gone into cross-platform GUI toolkits/frameworks like
wxWindows.

> I am certainly not against the OP trying to do something like this for
Boost
> but I think that is naive to assume that one can create such a Boost
> templated cross-platform framework without a tremendous amount of work and
> time spent invesigating the GUI and graphics APIs of a number of OSs. OTOH
> if the consensus is that such a framework will work only by having the end
> user plug-in to it classes with the appropriate functionality for a
generic
> idea, such as a listbox let's say, there will be enormous amount of work
for
> the end-user to do and even then the templated listbox may provide hooks
> into only a very small amount of functionality which listboxes represent
on
> that user's particular OS.
>
> As you have pointed out in the rest of your post, it may prove more
> worthwhile to work with the developers which already exist for a free
> cross-platform framework like wxWindows, in order to encourage them to use
> more modern C++ idioms which will make using their framework easier for
> end-users, than attempting to recreate one all over again. Boostifying
> wxWindows and having Boost developers and wxWindows talking to each other
> about better techniques for making wxWindows easier to program may be much
> more worthwhile than re-creating yet another GUI/Graphics framework.

That has also been my thought. As we've both pointed out, greating such a
library is a lot of work. There's a reason there's not yet a Boost.GUI.
There's a lot of developers at the wxWindows project, for example, showing
this. I just wanted to point out this point, too, to consider existing
libraries, as well. Boost has several times adopted libraries originating
elsewhere, and with an existing body of developers, as well, e.g.
Boost.Spirit.

The other mentioned cross-platform GUI similar in capability to wxWindows,
Qt, is not Open Source - there's an older Open Source non-commercial Windows
version, but not the more recent one, and not for commercial use. That makes
its license incompatible with Boost.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: GUI/GDI template library

2003-08-02 Thread Terje Slettebø
>From: "Edward Diener" <[EMAIL PROTECTED]>

> Add to this the fact that nearly every C++ programmer already works with a
> framework library depending on his implementation of choice. On Windows
> alone I know of WTL, ATL, MFC, OWL, VCL, wxWindows, QT, and no doubt
others
> about which I have no knowledde, each tied very closely to a particular
C++
> compiler, IDE, and implementation.

I just wanted to point out that several of these, Qt and wxWindows, are
cross-platform, so they are not tied to any specific compiler or platform.
wxWindows is also Open Source, and I've good experience with the little I've
used it. It's very easy to get up and running with it (at least it was on
Windows).

wxWindows is a wrapper for the native GUI API, while Qt emulates each GUI,
using only the low-level graphics API.

wxWindows could have been a candidate for Boost, had it not used "stone age"
C++ - no templates, exceptions and namespaces (essentially "C with Classes"
stage), to cater for a very broad range of compilers, even compilers such as
MSVC 4 (!). There are plans to change this, though
(http://www.wxwindows.org/roadmap.htm). To quote:

--- Start ---

Release 2.6.0 (stable)

Release date: end of September 2003

Release 3.0.0 (stable)

This release should finally mark the end of support for the antiquated
compilers without decent support of the modern C++ features such as
templates, exceptions and namespaces. wxWindows containers should be
replaced with the corresponding standard library classes and
std::basic_string<> should be used instead of wxString.

--- End ---

wxWindows also has 10 years of experience behind it, and an active developer
community.

Regarding what Dave Abrahams said in another posting about lack of templates
(regarding FLTK) meaning that smart pointers can't be used - well, in this
case, there are no exceptions, either, so you avoid problems with leaks from
exceptions. :)

Another note: The library is not a "lowest common denominator" library when
it comes to features. There's a core set of components, such as controls,
that are portable, but it also allows controls only available on one
platform. Thus, it's up to the user how portable, or platform-specific, they
want the application to be.

Hopefully, this may give some ideas in the debate.

Currently, Windows, Mac and Linux is supported, and an emulated version,
wxUniversal (like Qt is doing it) is also worked on, e.g. for embedded use
(http://www.wxwindows.org/wxuniv.htm).

As to the discussion of encoding the layout in code, or using some sort of
resource files, I think resource files may be preferrable for a few reasons:

- You don't have to recompile the program for every GUI change, when
designing the GUI
- It's usually easier to make GUI designing programs for resource files,
than ones generating source code. Besides, would you like "wizard-code" in
your program, a la MFCs or Javas?
- The layout and content may be changed at run-time, for example for
localisation or customisation. No need for recompiling a client's code; just
replace the resource files.

Often, someone else but the programmer, a designer, makes the GUI design,
and they should not have to be programmers. The same goes for web GUIs - a
typical way of doing it is having a designer create the HTML, which is then
used as some sort of template in the system, filling it in and transforming
it, e.g. using PHP.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] date_time, lexical_cast and MSVC 7.0

2003-06-24 Thread Terje Slettebø
>From: "Philip Miller" <[EMAIL PROTECTED]>

> Now, the reason for my posting.  I am using MSVC 7.0 and am unable to
> compile the date_time library tests.  Compiling time_parsing.hpp gives
> me an error in lexical_cast, where there is no output operator for the
> lexical_cast compiled for the function
> parse_delimited_time_duration.But the test regression results for
> date_time indicates that all tests pass for MSVC 7.0.  What am I doing
> wrong?

It could be a couple of things going wrong. First, there were some problems
with lexical_cast that were discovered after 1.30 was shipped, so they are
fixed in the CVS, but not in the file release. Unless you've done it, I
suggest getting the latest file from the CVS.

Secondly, unless you already have it, try enabling wchar_t as an intrinsic
type (option "Zc:wchar_t"). Otherwise, it will treat unsigned char and
wchar_t as synonyms.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Math Constants Formal Review

2003-06-22 Thread Terje Slettebø
>From: "Daniel Frey" <[EMAIL PROTECTED]>

> On Sun, 22 Jun 2003 22:01:19 +0200, Terje Slettebø wrote:
> >
> > Another thing, are the ADD_OPERATOR macro in your code necessary? It
> > compiles fine without it on Intel C++ 7.1.
>
> The GCC doesn't work without the operators, as it doesn't implicitly tries
> to satisfy float*pi_t by casting pi_t to float to use float*float. I
> think this is OK as the language can go for two ways:
>
> a) define float*float and use a promotion/conversion for, say, float*int.
> b) define several operators float*float, float*int, ...
>
> if it's b), the compiler cannot cast pi_t to float as it doesn't know
> whether to select float*float or float*int, thus it fails. Maybe a
> question for the language lawyers over at csc++ to find out what's
> correct.

It's an odd thing, anyway. Both g++ 3.2 and MSVC 7.1 complains that there's
no matching operator*.

> >> Also, I'm not sure whether it's standard compliant code.
> >
> > I think it is. It specialises a member. What could be the problem with
> > this? As you say, errors are caught at link time.
>
> I think that you have to declare the specialization in the class'
> definition, not just outside. But I may be wrong here and I haven't
> checked it.

I don't think so. I tried that, and it gave the error: "error: explicit
specialization is not allowed in the current scope"


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Math Constants Formal Review

2003-06-22 Thread Terje Slettebø
>From: "Daniel Frey" <[EMAIL PROTECTED]>

> On Sun, 22 Jun 2003 03:32:52 +0200, Terje Slettebø wrote:
> >
> > --- Start ---
> >
> > #include 
> >
> > #define BOOST_DEFINE_MATH_CONSTANT(name)\ const struct name##_type\
> > {\
> >   name##_type() {}\
> >   template\
> >   operator T() const;\
> > } name;
> >
> > #define BOOST_MATH_CONSTANT_VALUE(name, type, value)\
> > template<>\
> > name##_type::operator type() const { return value; }
> >
> > --- End ---
> >
> > My question is: Is there any reason why it can't be done this simple?
>
> Yes. AFAICS wrong use of your constants with unsupported types is only
> cought at link-time, not at compile-time. This is IMHO a big problem, big
> enough to reject this approach.

Ok. So maybe an extra level of indirection, as in your code (and
Kenniston's) may be preferable. I was wondering what was the point with it.
:)

Another thing, are the ADD_OPERATOR macro in your code necessary? It
compiles fine without it on Intel C++ 7.1.

> Also, I'm not sure whether it's standard compliant code.

I think it is. It specialises a member. What could be the problem with this?
As you say, errors are caught at link time.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Question about lexical_stream::operator<< and >>

2003-06-21 Thread Terje Slettebø
(Because this reply is so late, I cc it, as well)

Sorry for the late reply.

> I #included  and  in my
> code, and they indirectly #include . Here is the warning
I
> get from the compiler (I am using MS Visual C++ 6):
>
> *
> d:\documents and
>
settings\administrator\desktop\dev\boost_1_30_0\boost\lexical_cast.hpp(147)
> : warning C4800: 'void *' : forcing value to bool 'true' or 'false'
> (performance warning)
> d:\documents and
>
settings\administrator\desktop\dev\boost_1_30_0\boost\lexical_cast.hpp(146)
> : while compiling class-template member function 'bool __thiscall
> boost::detail::lexical_stream std::char_tr
> aits,class std::allocator > >::operator <<(const class
> std::basic_string,class
> std::allocator > &)'
>
> and others like this
> *
>
> And here is the line that causes this warning. First off, it's not clear
why
> the return should be a bool, and if that was indeed the author's
intention,
> the conversion between the ( stream << input ) which normally should
return
> a stream&, and bool, does not seem to make sense (for one thing the return
> will never be false).
>
> **
> bool operator<<(const Source &input)
> {
>   return stream << input;
> }
> **
>
> Could somebody clarify this.

First, the above warning has been fixed in the latest CVS version (this
issue was brought up a while ago, too). The function is now defined as:

bool operator<<(const Source &input)
{
return !(stream << input).fail();
}

This removes the warning, and does the same as the implicit conversion to
bool did.

The reason the implicit conversion to bool works is that std::stringstream
has an implicit conversion to void *, to give the stream's state. It returns
zero for fail(), and non-zero otherwise, so converted to bool, it becomes
the same as !fail(), as shown above.

Conversion to void *, rather than the apparently more obvious bool is to
avoid the possibility of it being erroneously used in arithmetic expressions
that way, such as:

int value=cin + cout;

There's also a "safe bool" technique, which avoids the possibility of the
conversion to void * being used for something else, like "delete cout;".
That technique is used in Boost ("safe_bool").


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Math Constants Formal Review

2003-06-21 Thread Terje Slettebø
I've finally managed to catch up with mailing list postings, and have now
read through the review postings of this library.

First, I'd like to thank Paul for the work he's done with the library,
having gone through no less two formal reviews (a dubious pleasure that
Robert Ramey may experience with his serialisation library, as well).

I've read through the docs, and also tested the library. I'd first like to
do a mini-recap of Paul's recap of the options available in the library
(present in the library in order to be able to discuss them in the review).
There are several ways the constants are represented:

1. Macros - #define BOOST_PI 3.14
2. Constant variables (for float, long and long double, a file for each) -
const type pi=3.14
3. Functions - type pi() { return 3.14; }
4. Kenniston's approach - an object with implicit conversions to any type
it's defined for. More of that below.
5. Interval constants. I won't go into these here. These appear independent
of the above constants, and may be implemented using the same ways.

Then we have Daniel's approach, as described in a posting. Also more of that
below.

Kenniston's approach
=
It works as follows (quoting from the library):

real_cast.hpp
---

template< typename Tag >
struct real_type
{
  template< typename Target >
  inline operator Target() const { return constant_value( static_cast<
Target * >( 0 ), *this ); }
};

pi_constant.hpp
--

#include 

struct pi_tag;

typedef real_type< pi_tag > pi_t;

extern pi_t pi; // Defined in pi_constants.cpp

inline float constant_value( const float *, const pi_t & )
{
  return 3.1F; // Simulating VERY low precision pi as float.
}

// Same for double and long double

That's it.

There are some components in the Kenniston version that appear to be not
needed, at least if you use other appropriate ways, such as real_cast:

template< typename Target, typename realType >
inline Target real_cast( const realType & real, const Target * target = 0 )
{
  return constant_value( target, real );
}

This is used in a couple of places, such as a few convenience overloaded
operators, like:

  template< typename Target, typename Tag >
   inline Target operator+( const Target & lhs, const real_type< Tag > &
rhs )
  { // For example: 2.F + pi
   return lhs + real_cast< Target >( rhs );
  }

However, at least when testing the library on Intel C++ 7.1, these operators
weren't needed. The reason is that the templated conversion operator of
real_type automatically performs the appropriate conversions, according to
the arguments used, just as if ordinary variables and constants are used in
expressions.

Thus these operators doesn't appear to be needed. Another place real_cast is
used is when the constants are referred to directly, without other
operators, so you may need to provide the type you want the constant value
as. The library uses:

cout << boost::math::real_cast(pi) << endl;

However, a just as good way, which may well be clearer, as it requires no
new casts, is:

cout << (double) boost::math::pi << endl;

Note that, as has been pointed out in this thread, this doesn't perform any
conversion of the constant value - the cast is just used to select the
appropriate conversion operator instantiation, just like real_cast, above.

Now, let's cover Daniel's approach.

Daniel's approach
==
This is similar to Kenniston's, except that it uses specialisation, rather
than overloading.

// Generic base class for all constants
template< typename T, template< class > class F > struct constant
{
// A cast-to-anything-operator :)
template< typename U > operator U() const { return F< U >()(); }

#define ADD_OPERATOR( OP ) \
template< typename U > friend U operator OP( const T& lhs, const U&
rhs ) \
{ U nrv( static_cast< U >( lhs ) ); nrv OP##= rhs; return nrv; } \
template< typename U > friend U operator OP( const U& lhs, const T&
rhs ) \
{ U nrv( lhs ); nrv OP##= static_cast< U >( rhs ); return nrv; }

ADD_OPERATOR( + );
ADD_OPERATOR( - );
ADD_OPERATOR( * );
ADD_OPERATOR( / );
#undef ADD_OPERATOR
};

// Here's the definition for pi for all types (can be extended by UDTs):
template< typename T > struct pi_value;
template<> struct pi_value< float > { float operator()() const { return
3.14; } };
template<> struct pi_value< double > { double operator()() const {
return 3.1416; } };
template<> struct pi_value< long double > { long double operator()()
const { return 3.1415927; } };

// Here's the single line to create a useful interface
struct pi_t : constant< pi_t, pi_value > {} pi;

That's all there is to it.

There has also been a discussion of using expression template techniques for
optimising computations (and Daniel's library shows an example of that). A
couple of observations on that:

- This is possible using either Kenniston's or Daniel's approach, or
some

Re: [boost] Re: Any interest in a member function pointer ->functionpointerconverter? (a la boost::function)

2003-06-06 Thread Terje Slettebø
>From: "Bohdan" <[EMAIL PROTECTED]>

> IMHO a very useful addon to your library can be routine
> to convert class to function which calls class destructor.



> //no virtual functions, no runtime polymorphism
> void * ptr = new MyClass;
> destruct_fn_type df = destruct_fn();
>
> 
> df(ptr);

Right. Your code works fine, and is also completely independent of
function_ptr, so might be useful as a utility in its own right. :)

Anyway, regarding function_ptr, as modern C++ typically is generic, so that
an entity only need to be "callable" (a function object or function
pointer), and that function objects also supports binding of parameters,
function_ptr probably have little use in modern C++.

When it comes to APIs that use function pointers, it also needs to be a C++
API, as function_ptr can't be used as an "extern "C"" function. Also, the OP
at the newsgroup prefers a macro to do this, after all, to avoid even
stating the function signature.

It was an interesting challenge, anyway. :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Any interest in a member function pointer ->functionpointerconverter? (a la boost::function)

2003-06-06 Thread Terje Slettebø
>From: "Pavel Vozenilek" <[EMAIL PROTECTED]>

> "Terje Slettebø" <[EMAIL PROTECTED]> wrote in message
> news:[EMAIL PROTECTED]
> [snip]
>
> > int main()
> > {
> >   function_ptr fn;
> >
> >   // The rest the same
> >
> >   A a;
> >   int r=fn(&a, 3); // sets r to 9
> > }
> >
> Is it similar (in principle) to
> http://www.code-genie.com/cpp/articles/events/events.html (long text)?

Not quite. The attached code doesn't implement any closure. All it does it
to provide a convenient way of defining a functions, which then calls the
provided member function.

The following:

function_ptr fn;

gets essentially transformed to:

int unique_name(A* c, int a1)
{
  return (c->*&A::a_member)(a1);
}

"fn" is an object which has an implicit conversion to pointer to function,
giving a pointer to "unique_name". "unique_name" is guaranteed to be unique
for each member function pointer, as it uses the member function pointer as
part of its template-id.

It should theoretically be possible to bind arguments this way, as well, so
you implement a kind of closure, but that isn't currently implemented.

You might for example do:

A a;

function_ptr fn(&a, 1);

fn(); // Call (&a->*&A::a_member)(1)

However, in this case, with the current implementation, the bound arguments
would be per-class, not per-object, since they would be stored in the
"unique_name" function.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Any interest in a member function pointer -> function pointerconverter? (a la boost::function)

2003-06-06 Thread Terje Slettebø
In this comp.lang.c++.moderated thread
(http://www.google.com/groups?selm=2045294.t6ppZr3Erj%40technoboredom.net),
there was the following request:

--- Start quote ---

For some reason (I want to pass function pointers to certain libraries) I'd
like to convert a member function into a real function pointer. gcc has an
extension which can do that, but for portability I came up with this
solution:

[...]

// use it
class A
{
public:
  int a_member(int k)
  {
return k*k;
  }
};

int main()
{
  int (*fn)(A*, int)=bmfhelper(&A::a_member).getfun<&A::a_member>();
  A a;
  int r=fn(&a, 3); // sets r to 9
}

The duplication of &A::a_member as a function *and* a template parameter
looks awkward to me, but I can't figure out a way to avoid this. I somehow
need that bmfhelper function call to make the template value parameter
possible. Has anybody a better idea?

--- End quote ---

I immediately thought of boost::function, and suggested that. Then you could
write it like this:

int main()
{
  boost::function fn=&A::a_member;

  // The rest the same

  A a;
  int r=fn(&a, 3); // sets r to 9
}

However, it turned out that this couldn't be used for OP, as a real function
pointer, not a function object, was needed. That's understandable, if you
want to pass it to libraries that take a function pointer (for example
callbacks).

After some experimentation, for Hiram Berry and I, in the thread, we finally
arrived at a way it could be done, which may be used in practically the same
way as boost::function. It can be used like this:

int main()
{
  function_ptr fn;

  // The rest the same

  A a;
  int r=fn(&a, 3); // sets r to 9
}

It creates a function object, but it has an implicit conversion to a
function pointer of the specified type, which calls the member function,
using the given object and any parameters.

Could there be any interest in this? For cases where a function pointer,
rather than function object, is required.

I've attached a version that has been tested on Intel C++ 7.1 and g++ 3.2,
and it includes a test.

The current version handles from 0 to 2 parameters, but can be extended
arbitrarily. It should probably handle the same number of arguments as
boost::function. Alternatively, this capability might be incorporated into
boost::function, if possible.

For a comparison between function objects and function pointers, see
(http://www.boost.org/doc/html/function.misc.html).

Since the member function is called from the function, it still requires two
calls through function pointers, like boost::function. However, the pointer
itself only takes up the size of one pointer, and it may be used with
libraries requiring function pointers, as mentioned.

Feedback is welcome.


Regards,

Terje

#include 

namespace detail
{

  ///
  // function_ptr_baseN
  ///

  template
  struct function_ptr_base0
  {
  public:
typedef R (*ftype)(C *);
operator ftype() { return f; }

  private:
static R f(C *c) { return (c->*pmf)(); }
  };

  template
  struct function_ptr_base1
  {
  public:
typedef R (*ftype)(C *, A1);
operator ftype() { return f; }

  private:
static R f(C *c, A1 a1) { return (c->*pmf)(a1); }
  };

  template
  struct function_ptr_base2
  {
  public:
typedef R (*ftype)(C *, A1, A2);
operator ftype() { return f; }

  private:
static R f(C *c, A1 a1, A2 a2) { return (c->*pmf)(a1, a2); }
  };

  ///
  // function_ptr_impl
  ///

  template
  struct function_ptr_impl;

  template
  struct function_ptr_impl
  {
typedef R (C::*type)();

template
struct base : function_ptr_base0 {};
  };

  template
  struct function_ptr_impl
  {
typedef R (C::*type)(A1);

template
struct base : function_ptr_base1 {};
  };

  template
  struct function_ptr_impl
  {
typedef R (C::*type)(A1, A2);

template
struct base : function_ptr_base2 {};
  };

} // namespace detail

///
// function_ptr
///

template::type pmf>
struct function_ptr : detail::function_ptr_impl::base {};

///
// Test
///

class test
{
public:
  test(int v) : value(v) {}

  int f1() { return value; }
  int f2(int a) { return a+value; }
  int f3(int a) { return -a-value; }
  double f4(double a, double b) { return a+b; }

private:
  int value;
};

int main()
{
  test t(1);

  function_ptr f1;
  function_ptr f2;
  function_ptr f3;
  function_ptr f4;

  std::cout << f1(&t) << '\n'  // Prints "1"

Re: [boost] [lexical_cast] performance related feature

2003-06-05 Thread Terje Slettebø
>From: "Pavel Vozenilek" <[EMAIL PROTECTED]>

> lexical_cast<> constructs and destroys std::stringstream
> (including dynamic memory allocation/free.)
> each time a conversion is done.
>
> Maybe specialised version of lexical_cast<> can be developed
> which takes external, existing stringstream instance as
> template parameter and reuses it.
>
> Very rough idea:
>
> template
> Target lex_cast(Source s)
> {
> // clear ss
> ss << s;
> Target t;
> ss >> t;
> return t;
> }
>
> extern std::stringstream ss;
> std::stringstream ss;
> ...
> int a = 99;
> std::string s = lex_cast(a);

This used to be addressed in the "Future Directions" part of the
lexical_cast documentation, but I see that that section is now removed.
Maybe it should be put back, at least the relevant parts? Kevlin?

>From the CVS, that section used to read:

--- Start quote ---

Future directions

- Improved string handling, correctly accommodating wide character strings,
incompatible basic_string types, and empty strings.

- Optimize the use of a stream away for identity conversions.

- An interpret_cast that performs a do-something-reasonable conversion
between types. It would, for instance, select between numeric_cast and
lexical_cast based on std::numeric_limits<>::is_specialized. This would be
an interesting project, but there are no concrete plans to pursue this at
the moment.

- It is also worth mentioning future non-directions: anything that involves
adding extra arguments for a conversion operation is not being considered. A
custom keyword cast, such as lexical_cast, is intended to look like a
built-in cast operator: built-in cast operators take only a single operand.
Where a higher degree of control is required over conversions, the standard
stringstream offers a more appropriate path. Where non-stream-based
conversions are required, lexical_cast is the wrong tool for the job, and so
it won't be special-cased for such scenarios.

--- End quote ---

Note "anything that involves adding extra arguments for a conversion
operation is not being considered."


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Exception handling... it's time to fix thehttp://www.boost.org/more/error_handling.html

2003-06-05 Thread Terje Slettebø
>From: "Alexander Terekhov" <[EMAIL PROTECTED]>

> Terje Slettebø wrote in message <[EMAIL PROTECTED]>:

> >  > why shouldn't std::exception use std::strings?
> >
> > See here (http://www.boost.org/more/error_handling.html).

You should perhaps point out that this is from a comp.lang.c++.moderated
posting, and not a Boost posting, or it could be confusing. You give a link
at the end, but it's not obvious.

> http://groups.google.com/groups?threadm=3EC0ECAA.6520B266%40web.de
> (Subject: Exception handling... it's time to fix the standard)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Wish list for Date-Time library

2003-05-27 Thread Terje Slettebø
>From: "Ian Baxter" <[EMAIL PROTECTED]>

> I wish that the date time library could construct a ptime from it's own
> to_simple_string function.
>
> i.e time = time_from_string( to_simple_string( time ) );
>
> Strange to have library that can construct a time from a string, but not
> from a string it itself has produced.
>
> Also, with MSVC 7.0, the date time library produces the following error
(in
> lexical_cast)
>
> S:\lib\boost_1_30\boost\lexical_cast.hpp(147): error C2678: binary '<<' :
no
> operator found which takes a left-hand operand of type
> 'std::basic_stringstream<_Elem,_Traits,_Alloc>' (or there is no acceptable
> conversion)

Could you have given a code snippet to demonstrate it? I can't find any
lexical_cast-related Date/Time failures in the Win32 regression test tables.

Also, you may want to get the latest lexical_cast version from the CVS, as
some problems were fixed after 1.30 shipped.

However, in the test logs there are several errors for Comeau C++:

lexical_cast_test / como-win32
Run output:
Running 11 test cases...
..\libs\conversion\test\..\lexical_cast_test.cpp(73): error in
"test_conversion_to_char": test '1' == lexical_cast(1.0) failed [1 !=
0]
..\libs\conversion\test\..\lexical_cast_test.cpp(97): error in
"test_conversion_to_int": test 1 == lexical_cast(1.0) failed [1 != 0]
..\libs\conversion\test\..\lexical_cast_test.cpp(99): error in
"test_conversion_to_int": exception boost::bad_lexical_cast is expected
..\libs\conversion\test\..\lexical_cast_test.cpp(101): error in
"test_conversion_to_int": exception boost::bad_lexical_cast is expected
..\libs\conversion\test\..\lexical_cast_test.cpp(124): error in
"test_conversion_to_double": test 1.23 == lexical_cast(1.23) failed
[2061584302 != 3951034368]
..\libs\conversion\test\..\lexical_cast_test.cpp(125): error in
"test_conversion_to_double": test std::numeric_limits::max() / 2 ~=
lexical_cast(std::numeric_limits::max() / 2) failed
[4294967295 !~= 4292870144 (+/-0)]
..\libs\conversion\test\..\lexical_cast_test.cpp(149): error in
"test_conversion_to_bool": test true == lexical_cast(1.0) failed [1 !=
0]
..\libs\conversion\test\..\lexical_cast_test.cpp(172): error in
"test_conversion_to_string": test "1.23" == lexical_cast(1.23)
failed [1.23 != 2061584302]
..\libs\conversion\test\..\lexical_cast_test.cpp(173): error in
"test_conversion_to_string": test "1.1" ==
lexical_cast(1.1) failed [1.1 != 1908373954]
..\libs\conversion\test\..\lexical_cast_test.cpp(213): error in
"test_conversion_from_wchar_t": test 1.0 == lexical_cast(L'1')
failed [0 != 1]
Exception in "test_conversion_from_wchar_t": std::bad_cast: bad lexical
cast: source type value could not be interpreted as target
..\libs\conversion\test\..\lexical_cast_test.cpp(236): error in
"test_conversion_to_wchar_t": test L'1' == lexical_cast(1.0) failed
[49 != 48]
..\libs\conversion\test\..\lexical_cast_test.cpp(277): error in
"test_conversion_to_wstring": test L"1.23" ==
lexical_cast(1.23) failed
..\libs\conversion\test\..\lexical_cast_test.cpp(278): error in
"test_conversion_to_wstring": test L"1.1" ==
lexical_cast(1.1) failed

That's the only compiler reporting errors on the regression test, though.
For example, I don't get any errors on Intel C++ 7.1 in strict mode. Does
anyone have an idea of what could be wrong? What library/C back end is used
for Comeau C++, here?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: in/out parameters, codingstylesandmaintenance

2003-05-08 Thread Terje Slettebø
To Victor:

You still haven't replied to the posting below. Am I to take this to mean
that you have no answer, i.e. you were wrong but won't admit it? Or do you
tend to offend people for no reason, and not care about it?

If I don't hear anything from you, I'll assume both, because I have no
reason to believe anything else.

When you come with a claim like this, you should at least have the decency
to explain what you mean, so I can reply to it. Posting vague accusations is
simply bad manners.

(Note: I've asked him about a reply to the posting below, off-list, but got
no reply. I've also seen him post, after I sent the posting below. I would
have preferred to settle this off-list)


Regards,

Terje


>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> > >Do you still think I've got it backwards?

> >From: "Victor A. Wagner, Jr." <[EMAIL PROTECTED]>
>
> > in a word, yes.
>
> In what way?
>
>
> Regards,
>
> Terje
>
>
> > At Saturday 5/3/2003 12:42 PM, you wrote:
> > > >From: "Victor A. Wagner, Jr." <[EMAIL PROTECTED]>
> > >
> > > > "It's not possible"  --- JML
> > > > "Yes it isshow me an example" --- TS
> > > >
> > > > U, I think you got it backwards Terje
> > >
> > >No, I haven't, but I think you've misunderstood.
> > >
> > >I meant, show me an example of a function where you think it's
impossible
> to
> > >just use name, to convey the meaning.
> > >
> > >His statement was: "And as I've already point out, it's not possible to
> make
> > >a function's intent clear with a name."
> > >
> > >Do you still think I've got it backwards?
> > >
> > >It's an attempt of getting the discussion more concrete, with actual
> code.
>
> ___
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
>

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Quantity library: any interest?

2003-04-30 Thread Terje Slettebø
>From: <[EMAIL PROTECTED]>

> > Even if angle is added as a dimension, to an implementation using an
> > integer vector, it still wouldn't accommodate any other dimensions
> > added later, without rewriting the library and unit definitions.
>
> how about having the basic SI dimensions and a couple of extra
> "to-be-defined-by-the-developer" dimensions. In that case, full
> SI "compliance" and for those who want something extra they can have
> it. I saw one of the discussed unit libraries provided something
> like a dimension to be defined by the user/developer.

I think I know a way this may be done, now: Default parameters.

There's several ways of specifying a unit; one is to use a typelist, such as
"typedef mpl::vector_c<1,0,0,0,0,0,0> kg" (Dave Abrahams also showed this
approach at the recent ACCU conference), or use template parameters for the
dimensions. In both ways, defaults may be used (it's used internally for
mpl::vector, anyway). In fact, all could be defaulted (like mpl::vector<>),
giving in this case a dimensionless unit.

Named template parameters could be a possibility, as well, so you could do
"typedef unit, m<>, s<-2> > newton".


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] [Philip.Dunstan@nautronix.com.au: is_base_and_derivedbug?]

2003-04-29 Thread Terje Slettebø
>From: "Philip Dunstan" <[EMAIL PROTECTED]>


> Hi there,
>
> Should this work?

No. Template type deduction uses an object's static (declared) type, so in
this program, T=A, since the static type of pa is A*. That its dynamic type
is B* isn't taken into consideration, as template instantiation is done at
compile-time.


Regards,

Terje


> I've tried it using g++ 3.2 (redhat and cygwin) and borland c++ builder
> 5.6.4 and it fails on the assert for all of them.
>
> #include 
> #include 
>
> class A {};
>
> class B : public A {};
>
> template 
> bool isDerivedFromA(const T& t)
> {
> return boost::is_base_and_derived::value;
> }
>
> int main()
> {
> B b;
> A* pa = &b;
> assert(isDerivedFromA(*pa));
> return 0;
> }

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Quantity library: any interest?

2003-04-27 Thread Terje Slettebø
>From: <[EMAIL PROTECTED]>

> we use the int-based template approach for a couple of years now in
> our AGV controller software. We actually sometimes reach the stage that
> it works when succesfully compiled and linked. Since our control software
> is physics throughout (field of robotics), the type safety is very
> important. However, besides the basic SI units we also have 'angle'
> as a dimension which allows us to distinguish 'velocity' and 'angular
> velocity' for example. Hence, from out 'real user' experience (engineering
> point of view) it would be a necessity to add 'angle' as a dimension
> without breaking already defined quantities. Most (all?) units libraries
> already define 'angle' to be dimensionless, which is true in
> scientifically spoken, but pragmatically (engineering ;-) less handy.

There's another question. If we add angle as a dimension, then what kind of
angle is it? There are several kinds of angles, such as radians (plane
angle) and steradians (solid angle). If both were represented by the same
angle dimension, then it probably wouldn't make much sense to add radians
and steradians (and what would be the resulting quantity?), yet, the library
would allow it.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Quantity library: any interest?

2003-04-27 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> These are my (only slightly informed) opinions.  I've heard Walter
> Brown talk about angle in this context, which was a big influence.
>
> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> > Regarding this angle dimension, should it be treated like the other
> > SI-dimensions? That is, say that you represent an SI quantity/unit
> > with an integer vector giving the exponents:
> >
> > template
> > class quantity;
> >
> > If you multiply two quantities, you multiply the value and add the
> > exponents, so quantity<0,1,0,0,0,0,0,0>(10) *
quantity<0,1,0,0,0,0,0,0>(10)
> > = quantity<0,2,0,0,0,0,0,0>(100) (m * m = m^2)
> >
> > Would this hold for angle, as well?
>
> Yes. Angle is a dimensionless scalar (length/length).  All its
> exponents are zero.

Yes, Renej (in the posting I replied to) also pointed out that angle is a
dimensionless quantity. However, in their real-life experience, they found
it useful not to have it dimensionless, but instead having it as an
additional dimension, to be able to distinguish things like velocity and
angular velocity. It was in this context that I wondered how angle - as a
dimension - should be treated.

> > That is, does it make sense to say angle * angle = angle^2?
>
> Probably not, but only because angle * angle doesn't make much
> sense.  Does that ever come up in real life?

If it's a dimensionless quantity, it wouldn't matter (all exponents would
still be zero). However, as a dimension, it would give angle^2. That's what
I wondered about.

> > I understand that e.g. angle/s (angular velocity) makes sense, but
> > should a library allow any combination with angle and the other
> > dimensions?
>
> Not arbitrarily:

I meant - should it allow the same combinations as the other dimensions are
allowed. That is (simplified, using only one dimension):

quantity * quantity = quantity
quantity / quantity = quantity
quantity + quantity = quantity
quantity - quantity = quantity

> angle(pi/2) / mass(40);  // OK
> angle(pi/2) + mass(40);  // error

Let's again cast it in the quantity<> example template I gave in the last
posting, to examine it. Let's say that the angle is expressed in radians. We
then have:

template
class quantity;

typedef quantity<1,0,0,0,0,0,0,0> mass;
typedef quantity<0,0,0,0,0,0,0,1> angle;

angle(pi/2) * mass(40) = quantity<1,0,0,0,0,0,0,1>(pi/2*40) (rad * kg)
angle(pi/2) + mass(40)

The last one will be an error, as you said.

I'm guessing that the answer to my question is, yes, angle, when expressed
as a dimension, may be treated like the other dimensions.

There's also a question of what then if someone would like to add a money
dimension, to avoid having money be interchangeable with dimensionless
quantities. However, in this case, multiplying currencies with each other
really doesn't make any sense (e.g. USD(10)*USD(10) = USD^2?), which _would_
be allowed, if it used the same framework as above. Therefore, maybe money
is better treated in a different way, than with an exponent.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Quantity library: any interest?

2003-04-27 Thread Terje Slettebø
>From: <[EMAIL PROTECTED]>

Still on the subject of a quantity library.

> > There is DEFINITELY a need for this - and in the C++ Standard Library,
> > but the relative merits of the two proposals mae so far are not yet
> > clear to me.
> >
> > Perhaps we need more real user experience. (Or is the problem that the
> > MSVC compiler can't/couldn't handle the SIUnits code?)
>
> real user experience... you asked for it ;-)
> we use the int-based template approach for a couple of years now in
> our AGV controller software. We actually sometimes reach the stage that
> it works when succesfully compiled and linked. Since our control software
> is physics throughout (field of robotics), the type safety is very
> important. However, besides the basic SI units we also have 'angle'
> as a dimension which allows us to distinguish 'velocity' and 'angular
> velocity' for example. Hence, from out 'real user' experience (engineering
> point of view) it would be a necessity to add 'angle' as a dimension
> without breaking already defined quantities. Most (all?) units libraries
> already define 'angle' to be dimensionless, which is true in
scientifically
> spoken, but pragmatically (engineering ;-) less handy.

Regarding this angle dimension, should it be treated like the other
SI-dimensions? That is, say that you represent an SI quantity/unit with an
integer vector giving the exponents:

template
class quantity;

If you multiply two quantities, you multiply the value and add the
exponents, so quantity<0,1,0,0,0,0,0,0>(10) * quantity<0,1,0,0,0,0,0,0>(10)
= quantity<0,2,0,0,0,0,0,0>(100) (m * m = m^2)

Would this hold for angle, as well? That is, does it make sense to say angle
* angle = angle^2? I understand that e.g. angle/s (angular velocity) makes
sense, but should a library allow any combination with angle and the other
dimensions?

How do you treat angle in your own library?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] quantity.hpp uploaded into files section

2003-04-27 Thread Terje Slettebø
If one were to implement currency conversion, how might that be done, in
general?

Does one need to store the conversion rates between any two currencies
(giving an N^2 size table), or might it be possible to convert any currency
to some "universal currency", and from that again to any other, and still
getting the right values (giving a 2N table)?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: class proposal

2003-04-24 Thread Terje Slettebø
>From: "Noel Yap" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> > The compiler may elide such copy, even if the temporary being returned
is a
> > named variable, and several compilers (such as g++ and the EDG based
ones),
> > does this optimisation (RVO). For example:
>
> Playing devil's advocate, I think RVO can easily be fooled with
> not-so-tricky code.  If you're really concerned about this situation,
> use some sort of smart pointer.  For example:
>
>   boost:shared_ptr< T > f( boost::shared_ptr< T > const in_ );

The part about RVO was really concerned with the out() scenario, not
in_out(). I'm not sure if passing a smart pointer buys you very much. In
this case, the smart pointer is const but the pointee is not, so the "const"
in the signature is really just masking what is going on.

Furthermore, this means dynamical allocation (either by caller or callee),
which may be more expensive than making a copy on the stack (unless it's
elided), and passing that.

Yes, there are ways to write it so that RVO is disabled, but with careful
coding for this, such as using single exit, you can enable it, and it can be
tested for.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: class proposal

2003-04-24 Thread Terje Slettebø
Just to add some to my previous posting.

Also, from a maintenance POV, having variables that doesn't change
throughout a function (or program), tends to make it easier to understand.
Having functions which change their arguments goes rather against that.

One exception is input stream operators, where it's really no other way of
doing it than first declaring a variable, then streaming into it.

For example:

const some_type valueA=...;

const some_type valueB = f(valueA);

// Possibly many lines of code here

// What is valueA and valueB here? Answer: The same as when they were
declared.

Yes, I know it may be a massive undertaking to start making a program, which
wasn't designed that way, const correct. However, it may be one of the
better refactorings to do. It also highlights all the points where something
may be changed, and where further refactorings (such as those in the
previous posting) may be appropriate.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: class proposal

2003-04-24 Thread Terje Slettebø
>From: "Justin M. Lewis" <[EMAIL PROTECTED]>

> As for a function returning a single param, I agree, normally you'd just
> return it, UNLESS it's some big structure you don't want being copied
> all over the place, then passing it by reference to a function makes
> more sense.

The compiler may elide such copy, even if the temporary being returned is a
named variable, and several compilers (such as g++ and the EDG based ones),
does this optimisation (RVO). For example:

class big_class { ... };

big_class f(...)
{
  big_class temp;

  ...

  return temp;
}

 // Only the constructor is called, here, no copy constructor

big_class value = f(...);

Also, if you want to return multiple values, std::pair or boost::tuple may
be used for that, as Noel Yap pointed out.

I understand the motivation is to transform a lot of existing code into
something that may be more easily understood. However, an alternative to
your method is to use techniques that has been proposed in this thread. For
example:

int return_value = f(type &may_change, const type &may_not_change); //
Current function

int return_value = fA(c_out may_change, const type &may_not_change);
// Your method

boost::tuple fB(const type &may_not_change); // Alternative

Use:

type value;

int return_value = fA(out(value), const_value); // Your method

int return_value;

boost::tie(return_value, value) = fB(const_value);

Also, you may enforce that the parameters aren't changed, by using const:

const type const_value = ...;

fA(const_value, ...); // Error, can't bind to non-const reference

This may be a larger refactoring than adding out() and in_out(), though,
especially for a large code base, as you mention. I'm just concerned with
that out() and in_out() isn't a very common way to do it, so it may be best
to do it in an idiomatic way, to begin with.

Also, statements like:

boost::tie(return_value, value) = fB(const_value);

stands out in the code, rather than being more hidden with an out(). Thus,
they may have a better chance of being possibly further refactored. Say that
the return code says whether or not a valid object is returned. This may be
changed to:

boost::optional result = fB(const_value);

Or maybe throwing an exception would be more appropriate:

type value = fB(const_value); // Throws on failure

The point really is the same as with your proposal - making it explicit in
the code what is happening.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: class proposal

2003-04-23 Thread Terje Slettebø
>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> >From: "Justin M. Lewis" <[EMAIL PROTECTED]>
>
> > Well, I guess, based on all the code I've been reading at work it didn't
> > seem so small, chasing down all kinds of functions across 100's of files
> > to see why exactly values are changing mid function I'm looking at
> > without warning.
> >
> > Anyway, this would allow for stronger enforcement of the rule that
> > changing params should be marked somehow.  As the programmer of a
> > library people are using, I can force them to mark the params they're
> > passing as out or in_out, so in 5 years when someone else comes along
> > and has to debug it, it's all clear what's happening.
>
> Why not use T & if the function may change it, and const T & if it won't?

After I sent it, I realised that the issue was marking it at the _caller's_
side, so then this doesn't apply.

It was a little difficult to understand the proposal, as it mentioned
c_in_out and c_out, while the code example uses CRetVal and the retval
function.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: class proposal

2003-04-23 Thread Terje Slettebø
>From: "Justin M. Lewis" <[EMAIL PROTECTED]>

> Well, I guess, based on all the code I've been reading at work it didn't
> seem so small, chasing down all kinds of functions across 100's of files
> to see why exactly values are changing mid function I'm looking at
> without warning.
>
> Anyway, this would allow for stronger enforcement of the rule that
> changing params should be marked somehow.  As the programmer of a
> library people are using, I can force them to mark the params they're
> passing as out or in_out, so in 5 years when someone else comes along
> and has to debug it, it's all clear what's happening.

Why not use T & if the function may change it, and const T & if it won't?
Simple and clear. No need to use pointers, to differentiate between it.

An advantage with references is that you may pass by value, or const
reference, and to the caller, it's called in the same way, so the pass by
value or const reference may be an implementation detail.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Quantity Library

2003-04-20 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> At 02:28 PM 4/19/2003, Pavel Vozenilek wrote:
>
>  >  b7- ability to distinguish different types of the same dimension (e.g.
>  >width of image and width of screen)
>
> Other examples: It should be an error to try to add gallons of gasoline to
> gallons of propane. Not to mention trying to add gallons of unleaded
> regular gasoline to unleaded premium gasoline. Except that for certain
> purposes "hash totals" for example) there must be a way to do the
otherwise
> illegal operation.

Both of these might be possible to handle externally to a unit/quantity
library, by using different underlying types, e.g.:

class arithmetic // Provides arithmetic operations, like e.g. "double"

class image_type : public arithmetic { ... }
class screen_type : public arithmetic { ... }

length l1;
length l2;

new_length=l1+l2; // Error

You may argue that it should instead be part of the unit, itself, such as:

unit

However, this might make it harder to administer any conversions and their
products. You may not want to mix leaded and unleaded gasoline for your car,
but shouldn't a chemist be allowed to? By keeping the substance used as the
underlying type, you may provide any conversion between them.

Another thing is that differentiating between what is operated on (not just
units, like meter, dollars, etc.) may be beyond what a quatity library
should be concerned with. For example, should the following be allowed:

volume hydrogen;
volume oxygen

// ...

volume water=hydrogen+oxygen; // Bang? :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Passing template-ids as macro parameters

2003-04-17 Thread Terje Slettebø
>From: "Paul Mensonides" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> > Is there some way (using PP-lib, or whatever), to pass a template-id
> > with more than one parameter (thus, it contains at least one comma),
> > to a macro?
> >
> > E.g.:
> >
> > #define TEST(a) test t;
> >
> > TEST(std::pair) // Won't work
> >
> > Maybe some sort of variation of BOOST_PP_IDENTITY:
> >
> > #define BOOST_PP_IDENTITY1(a) a
> > #define BOOST_PP_IDENTITY2(a,b) a,b
> > #define BOOST_PP_IDENTITY3(a,b,c) a,b,c
> >
> > etc.
> >
> > TEST(BOOST_PP_IDENTITY2(std::pair)) // Now ok
>
> I'll answer all three of these emails at once, since they are about the
same
> thing.  First, the above will cause problems, specifically problems like
this:
>
> #define T1(a) T2(a)
> #define T2(a) test t;
>
> #define IDENTITY2(a, b) a, b
>
> T1(IDENTITY2(std::pair)) // error
>
> I.e. by the time that T2 is invoked, IDENTITY2 has already expanded, which
> yields too many arguments to T2.

Right. However, for simple use (only one level of macro expansion), this
works, and has the advantage of being simple and non-intrusive to use.

>  What we need is a general solution and a set
> of conventions for passing types.  This is difficult without variadics to
do
> with the preprocessor itself.  Specifically, you have to use the core
language:
>
> template struct wrap {
> typedef T type;
> };
>
> template struct wrap {
> typedef T type;
> };
>
> #define TYPE(x) wrap::type
>
> TYPE((int))  // okay
> TYPE((std::pair)) // okay
>
> However, this has its own problems.  Specifically, it is using function
types to
> store the type--which is inside parentheses and therefore protected from
the
> preprocessor.  The use of function types with cause certain things to
error:
>
> TYPE(( void )) // error
> TYPE(( int (int, int) )) // function type altered to pointer-to-function
> TYPE(( int[2] )) // array altered to pointer

Right. It's similar to Aleksey's "round lambda".

> There is only one other language construct that might be of use here:
> pointers-to-members.  Specifically, it is parenthesized, yet does not
undergo
> promotion/alteration when used in a parameter list.  However, it is
intrusive:
>
> template struct wrap;
> template struct wrap {
> typedef T type;
> };
>
> #define TYPE(x) wrap::type
>
> TYPE(( std::pair::* ))
>   ^^^
> Also, this cannot be used for non-class types--which can still have commas
in
> them:
>
> template struct typelist {
> typedef T head;
> typedef U tail;
> };
>
> TYPE(( typelist::head::* )) // error
>
> So, without variadic macros, there is no "good" solution.  Instead, you
have to
> resort to hacks that require you to know the number of unbound commas in
the
> type:
>
> #define IN(s, x) (s) x
> #define OUT(x) BOOST_PP_TUPLE_REM x
>
> #define M1(type) M2(type)
> #define M2(type) OUT(type)
>
> MACRO( IN(2, (std::pair)) )

I'm not sure how this latter solution could be used. How could MACRO
retrieve the type being passed?

Thanks. :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Adding a generic list manipulator

2003-04-17 Thread Terje Slettebø
Another suggestion, which was also suggested, and done, for my composite
stream operators (which is similar to your library), is to put it in the
Sandbox. That enables easier use and updating, and you don't have to attach
a file for each update.

People using the Sandbox can just add it to their include path, and use it
like Boost (same "boost" path prefix for the libraries).

The composite operators are at boost-sandbox/boost/io/format and
boost-sandbox/libs/io/format, and I'll add some docs, soon, as well. I'm
sure there's room for more such libraries, there. :)

Maybe a combined library could come from this. Anyway, several libraries
enables experimentation, as well.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] bad_lexical_cast

2003-03-31 Thread Terje Slettebø
>From: "Alisdair Meredith" <[EMAIL PROTECTED]>

> I see that this has been the topic of much discussion lately, but just
> confirming this little warning from the regressions has not snuck by
> unnoticed:
>
> # 'boost::bad_lexical_cast::what()' hides inherited virtual function
> 'std::exception::what() const'
>
> [const missing, to state the obvious]
>
> This apparently only affects 3 compilers on Windows, haven't
> cross-checked the other platforms.

Thanks for pointing this out. It's fixed now.

Yeah, oddly enough, this gave no warning, even when running on the highest
warning level, and strict mode, on Intel C++ 7, and MSVC 6/7.

Also, the tests only checks that the exception is thrown when it's supposed
to, it doesn't check what().


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] lexical_cast woes

2003-03-30 Thread Terje Slettebø
>From: "Michel André" <[EMAIL PROTECTED]>

> I get the following errors when compiling with the lexical_cast version in
> CVS on MSVC 7.0 do I have to enable wchar_t support on the command line or
> disable it via  DISABLE_WIDE_CHAR_SUPPORT or whats the solution.

This problem was reported at the Boost-Users list, as well. It turns out
that testing for MSVC 6, and disabling wide character support in that case,
wasn't enough, as the same needs to be done if MSVC 7 is set to have wchar_t
not as intrinsic type.

I've therefore removed the "BOOST_MSVC <= 1200" test, again, and restored
"BOOST_NO_INTRINSIC_WCHAR_T" test, which used to be, earlier.

The reason the the test for MSVC was used first, was that the config for
Intel C++ also defined BOOST_NO_INTRINSIC_WCHAR_T, regardless of whether it
was the case or not, as the compiler didn't set a macro for it. However, it
appears that the latest version of Intel C++ do get correct wide character
support, when it's enabled.

I've also changed bad_lexical_cast, to return the types used, in
source()/target(), as given in Kevlin's suggestion
(http://article.gmane.org/gmane.comp.lib.boost.devel/18240).

As a small change, the warning with MSVC 7 for void * -> bool conversion is
removed, using Kevlin's suggestion
(http://article.gmane.org/gmane.comp.lib.boost.devel/18253).

I've run the tests for Intel C++ 7.0 (strict mode), MSVC 7.0 (with and
without wchar_t as intrinsic type), and MSVC 6.0, and it works.

This is now fixed in the CVS.

Thanks for the feedback.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-28 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >
> > >From: "Jason House" <[EMAIL PROTECTED]>
> >
> > > 1. Is it at all useful/possible to use a lambda-like notation?
> >
> Thinking about it more, I don't know how doable it is for the first 3
> parameters...
>
> But what about:
>
> /* brain dead function to serve as example */
> std::string printable(char z) {return z=0?"\0":std::string(z);}
>
> char x[7] = "foobar";
> std::cout
><< io_format("{", "}", ", ", "'" << printable(_1) << "'")
><< "x = " << x;
>
> output:
> x = {'f', 'o', 'o', 'b', 'a', 'r', '\0'}
>
> alternates like (printable(_1) or just "'" << _1 << "'" would also work.
>
> That makes the visitor possible, but also makes the inspiring case for
> the extra inputs to io_format be a little more readable...

This still wouldn't, in itself, support things like outputting indices,
though, unless the entity being passed may hold state, such as a function
object.

It also looks like quite a bit more complex, apparently much of it just to
be able to write "\'" << _1 << "\'" instead of "\'","\'".

There's another issue: The type of the lambda expression would likely encode
the expression, meaning you have an issue of how to store and retrieve it,
unless you know the exact type of the object to retrieve.

This is the code to retrieve the format_data object for a given type (given
with "index"):

template
static format_data &format(std::basic_ostream
&stream)
{
  void *&void_ptr=stream.pword(index);

  if(!void_ptr)
void_ptr=new format_data(default_data);

  return *static_cast *>(void_ptr);
}

How to do that, if the object being retrieved is an arbitrary type?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-27 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> I had 2 thoughts today...
>
> 1. Is it at all useful/possible to use a lambda-like notation?

In what way? Could you have given a rough syntax-example?

An example in BLL is:

std::for_each(v.begin(), v.end(), std::cout << _1 << '\n');

>In the past, I've liked the look of that a lot.
>(the comments about alternate notation made me think of it)
>
> 2. Why are we restricting the output to strings?

That _is_ a natural question, isn't it? :)

>Couldn't the types of the 3 delimiter strings actually be
>implicit template parameters?
>(the char/wchar versions made me think of that)

Yes, that is how it currently works; it deduces the types passed to the
format function template, and returns an object of type format_type
(analogous to many cases, such as bind1st/binder1st).

Since all the string parameters have default to empty string, this is done
by having three overloads of the format function template - for
std::basic_string, const char * and const wchar_t *. That way, you can use
"", L"", etc. as appropriate, for the default.

As mentioned in some previous postings, a possibility for generalising the
formatting could be to pass a "visitor" object to the format-function,
instead of the strings, which is then invoked at the specific times during
output (begin/end sequence, etc.). One could then also support things like
line numbers and indentation, without hardcoding how this is done. It would
also be possible to make a visitor object which took strings in the
constructor, and gave the current semantics.

This approach seems to require dynamical allocation of the format data, and
virtual functions, though. Since this means quite a bit of change, I haven't
done it so far, but I'm open to the possibility.

An example of its use:

// Line numbering visitor (could be included in the library)
//
// All virtual functions are included for illustration. In practice, the
once with empty body could be omitted.

template
class numbering_type : public visitor_base
{
public:
  explicit numbering(int ln) : line_number(ln) {}

  virtual void start_sequence(std::basic_ostream
&stream) {}
  virtual void end_sequence(std::basic_ostream &stream)
{}
  virtual void element(std::basic_ostream &stream,
const T &element)
{ stream << line_number << ' ' << element << '\n'; ++line_number; }

private:
  int line_number;
};

// The numbering function template returns a numbering_type object

typedef std::vector vector;

vector v;

// Fill vector

std::cout << format(numbering())
  << v;

Output:

1 - A
2 - B
3 - C

etc.

Thanks.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-26 Thread Terje Slettebø
>From: "Rozental, Gennadiy" <[EMAIL PROTECTED]>

> > Another way may be a macro. However, as has been mentioned in
> > this thread,
> > it appears that the config macros aren't geared for macros
> > with optional
> > exclusion of RTTI.
>
> No. this has nothing to do with config

Well, as Dave A said in another mail, there is already a config macro to
disable exceptions. Whether or not libraries check for it is optional,
though. From the docs:

"BOOST_NO_EXCEPTIONS - The compiler does not support exception handling
(this setting is typically required by many C++ compilers for embedded
platforms). Note that there is no requirement for boost libraries to honor
this configuration setting - indeed doing so may be impossible in some
cases. Those libraries that do honor this will typically abort if a critical
error occurs - you have been warned!"

Embedded C++ doesn't have RTTI, either. Therefore, a BOOST_NO_RTTI might be
reasonable, as well.

I understand that your suggestion is not for macros describing lack of
compiler support, but rather user settings. Yet, couldn't these be used for
either, by explicitly setting them before any Boost includes?

Having a lexical_cast-specific macro will just cover that component, while
the same issue could occur with another library, unless a Boost-wide
configuration macro is used.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-26 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> "Rozental, Gennadiy" <[EMAIL PROTECTED]> writes:
>
> >> Even if none of the above looks sound for you I still argue that
> >> lexical_cast *should not force* inclusion of typeinfo. It's not
> >> "inconvinience" - it's showstopper. It's much more important
> >> than providing
> >> specific type info. In majority of the cases one knows it anyway.
> >>
> >> > Kevlin
> >>
> >> Gennadiy.
> >
> > So. Are we gonna stuck  with typeinfo in lexical_cast?
> >
> > Could we have at least some discussion about this?
>
> My contribution to the discussion is that I don't think supporting C++
> language subsets is worth complicating the interface in the way you
> propose.  Maybe lexical_cast(whatever) should return 0 on failure
> and that should be enough for those who can't handle the exceptions we
> want to throw... though I don't know how (or if) that interacts with
> things like char const*.

Technically, this should be possible, since it now throws an exception if
you try to convert to any pointer, as it checks for that. This is to remove
the possibility of trying to convert to char *, which could otherwise
succeed (due to the design of basic_istream), but would give undefined
behaviour.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-26 Thread Terje Slettebø
>From: "Rozental, Gennadiy" <[EMAIL PROTECTED]>

> > #include 
> > #include 
> > #include 
>
> I am afraid boost/io/format will be confusing in a sight of presence of
> Boost.Format.

I understand. Well, it's in a different namespace.

> I would prefer (since it all about container output formatting)
>
> boost/io/container

Well, it actually may handle any composite type, such as std::complex,
std::pair, etc., as well. It also handles any sequence (using
io::sequence(begin,end) ), not just containers.

I used to call it "composite_format", but that was rather long... Using
"io::format(...)", I think is quite succinct.

> Also it could be stl instead of std, though it's the matter of taste.

The directories follow the namespaces, so it has "std" and "boost". STL is
only a subset of the standard library, so also for that reason, I think
"std" would be more appropriate.

> > std::cout << format("[", "]\n", " => ")
> > << format("","","")
> > << values;
>
> ...
>
> > Syntax
> > --
> > format(, , , [ > element>, ])[.set_default_format()]
> > format()
>
> I personally would really prefer verbose format specification. So I should
> not remember what each of the parameters means by it's position.
> Something along this lines:
>
> std::cout << start_elelment( "[" ) // if you need value
> type_here. I am not sure

Yes, you do, or it won't know which type to set it for.

>   << end_element( "]\n" )
>   << element_delimeter( " => " )
>   ...
>   << values;
>
> Or
>
> std::cout << format().start_elelment( "[" ).end_element( "]\n"
> ).delimeter( " => " )
>   ...
>   << values;
>
> Or mix of this styles. Or - the very best - all of them.

This should be quite easy to add. The latter style is also used in Reece
Dunn's list manipulator, which also deals with output for sequences.

I don't have that much practice with it, but I've found myself that I don't
have a problem remembering which parameter is what, in the 3+2 optional
parameter list. Lack of verbosity may be considered one of the advantages
over writing explicit output code.

Thanks for the feedback.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-26 Thread Terje Slettebø
>From: "Rozental, Gennadiy" <[EMAIL PROTECTED]>

> > Even if none of the above looks sound for you I still argue that
> > lexical_cast *should not force* inclusion of typeinfo. It's not
> > "inconvinience" - it's showstopper. It's much more important
> > than providing
> > specific type info. In majority of the cases one knows it anyway.
> >
> > > Kevlin
> >
> > Gennadiy.
>
> So. Are we gonna stuck  with typeinfo in lexical_cast?
>
> Could we have at least some discussion about this?

I'd certainly be open to make the type_info part optional. A question is how
to do it.

Using policies may complicate the interface, and from earlier discussions,
and also from the earlier "Future directions" part of the docs, it turned
out that adding new parameters weren't deemed acceptable (due to it no
longer looking like a cast in that case).

Another way may be a macro. However, as has been mentioned in this thread,
it appears that the config macros aren't geared for macros with optional
exclusion of RTTI.

Then one might have a lexical_cast specific macro for it, like
BOOST_LEXICAL_CAST_USE_RTTI, like you suggested.

Kevlin or others, any thoughts?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-26 Thread Terje Slettebø
Hi.

I've now uploaded the latest version of the composite stream operators
library at Yahoo Files
(http://groups.yahoo.com/group/boost/files/composite_stream_operators/) and
the Sandbox (boost/io/format/ and libs/io/format)..

Since the libraries in the Sandbox use the boost namespace, this one does
the same. All components are in the boost::io namespace.

There are no docs, yet, but there are several test programs, illustrating
use for all supported types (the list of these are given below). I also
include information here.

Feedback is welcome.

Examples of use:

std::vector
---
#include 

std::vector v;

// Fill vector

// Output (using user-changeable default format)

std::cout << v;

Output:

[1,2,3,4,5,6,7,8,9,10]

std::map

#include 

typedef std::map map;
typedef map::value_type value_type;

map values;

// Fill map

std::cout << format("[", "]\n", " => ")
<< format("","","")
<< values;

Output:

[1 => A]
[2 => B]
[3 => C]

Array
---
#include 

int array[]={1,2,3,4,5,6,7,8,9,10};

std::cout << array << '\n'
<< format<_ (&)[N]>("", "", "\n")
   << array;

Output:

[1,2,3,4,5,6,7,8,9,10]

1
2
3
4
5
6
7
8
9
10

Here is a synopsis
--

namespace boost::io
-

format - Set output formatting
==

Type options
--
"_" - Any type
"N" - Any size (for array)
template_name<_> - Any instantiation of the given template (may need more
"_"s, one for each parameter without default)

Syntax
--
format(, , , [, ])[.set_default_format()]
format()

If set_default_format() is used, it may be used without a stream, and it
then sets the format for all streams.

Examples
--
stream << format >(...) // Set format for std::vector
stream << format >(...) // Set format for any instantiation
of std::vector
stream << format<_>(...) // Set format for any type

stream << format >(false) // Unsets format for
std::vector

It checks for format settings, going from the most specific to the most
general, stopping when it has found a set format. E.g. for the above
example, this means checking in the following order:

std::vector
std::vector<_>
_
_ (any stream)

The library sets the following default for all streams (the last format
checked), which may be changed by the user. This default is set rather
arbitrarily, and is open to change. This is so that no formatting is needed
to be set, to get useful output:

format<_>("[", "]", ",").set_default_format() - Sets format for all types,
for all streams.

It also handles wide character formatting:

format(L"[", L"]", L",")

sequence - Lets a sequence, given with start/end iterators, be output as the
given type
==

Syntax
--
sequence(, )

Examples
--
#include 

std::vector v;

// Fill vector

std::cout << sequence<_>(v.begin(),v.begin()+10);

Output:

[1,2,3,4,5,6,7,8,9,10]


typedef std::istream_iterator in;

std::cout << sequence<_>(in(std::cin),in());

Input:

1 2 3 4 5 6 7 8 9 10

Output:

[1,2,3,4,5,6,7,8,9,10]

wrap - Lets a type be output using set format, even if it has its own output
operator
==

Some types, such as std::complex, std::bitset, and boost::dynamic_bitset
have already output stream operators defined, so to set their format, one
may wrap the value before outputting.

Syntax
-
wrap()

Examples
--
#include 

std::complex value(1.23, 2.34);

std::cout << value << '\n'
<< wrap(value);

Output:

(1.23,2.34)
[1.23,2.34]

Supported types
=
Arrays

std

pair
complex (has output operator, use wrap)
vector
list
deque
set
multiset
map
multimap
bitset (has output operator, use wrap)

boost

dynamic_bitset (has output operator, use wrap)

The supported types may also be extended by the user.

Header organisation

boost/io/format ---
   |--- std
   |--- boost

libs/format/io  ---
|--- tests

Compatibility
==
The library uses standard C++, but isn't very portable currently. It has
been tested on Intel C++ 7.0 and g++ 3.2.

I plan to work on the portability, and should soon get it to work on MSVC,
etc., as well.

The names, syntax and semantics is open to suggestions for change.

I hope Daryle Walker doesn't mind that this library is sharing the "io"
directory and namespace, at the Sandbox. If so, I could change it from
"io/format" to "io_format".

Thanks for the patience to those who have waited for this update.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> What I meant (though sorry I was probably too blunt about it) was that
> >> it's irrelevant whether you actually observed termination or not,
> >> unless you're intending for lexical_cast to work just on that compiler.
> >
> > That's correct, and I meant nothing else, either.
>
> If you understood all along that the copy ctor of your exception class
> could cause termination when the exception was thrown, I don't
> understand why I went through this long twisty discussion just to have
> you tell me so.

What happened was:

1. You told me it could cause termination.
2. I made a test case, and observed that it didn't cause termination on
construction, and that due to the implementation, no copy was made, so it
didn't test the copying (which may cause termination).
3. You said it was irrelevant that no termination was observed.
4. I said that I hadn't claimed the test proved there would be no
termination, since on that platform, the copying wasn't tested.

As you can see, I agreed with you from the beginning. It just seems that you
thought I claimed that since it didn't terminate, it wouldn't do that on any
platform. I didn't mean that, and it seems this misunderstanding was the
cause of this long discussion.

> > I wouldn't have made this such a big issue had you not claimed the
> > implementation didn't do what was requested, when both that and your
> > suggestion implements the request.
>
> I think there's a stronger argument for type_info being a
> representative of the type, because among other things an
> implementation is allowed to have type_info::name() return the empty
> string for all types.

I don't disagree with that. I merely made the point that my implementation
also fulfilled the request, which it seems you now agree to, as well.

I also think returning the type as type_info is better.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> >> > As it stands, it prints "Exception - Constructor", as it throws
> >> >> > an exception in the constructor of the Exception exception. If
> >> >> > the throw-statement in the constructor is commented out, it
> >> >> > prints "Exception - Exception", apparently not invoking the copy
> >> >> > constructor when throwing the exception (which it's allowed to).
> >> >>
> >> >> Irrelevant.  A program that invokes undefined behavior may appear to
> >> >> work fine also.
> >
> > I did not state the latter part as a general claim, which is why I said
that
> > eliding the copy is something it's allowed to, but not required to.
Thus,
> > there's no argument to consider "irrelevant".
>
> What I meant (though sorry I was probably too blunt about it) was that
> it's irrelevant whether you actually observed termination or not,
> unless you're intending for lexical_cast to work just on that compiler.

That's correct, and I meant nothing else, either.

> >> > The reason the extended error type was added, was that there has
> >> > been requests on this list for storing the types used in the
> >> > conversion, in the exception, to make it easier to know which
> >> > conversion failed.
> >>
> >> That's a good request, but you didn't do that, did you?
> >
> > Let me rephrase it: IIRC, the request was for storing information about
the
> > types used, not how this was to be done. Thus, whether or not this does
what
> > was requested depends on how to interpret the request.
> >
> > The suggestion to store (pointer/reference to) type_info objects doesn't
> > store the types, either; it stores information about them, this time in
a
> > way easier for the program to use.
> >
> > So, I can just as well say as you say: The suggestion you said you meant
> > (storing references to type_info objects) doesn't do that, either, does
it?
>
> Ugh.  As far as it's possible to store a type at all in C++, yes my
> suggestion does store the types.

No, it doesn't; it stores a reference to an object describing them. My
version stored a string describing them. I just applied the same
hair-splitting reasoning that made you categorically state that my
implementation "didn't do that" (what was quoted as requested). My
implementation do it just as well as your suggestion, both stores
information describing the types. One is geared towards user-readable
information, one is geared towards program-readable information. Agree?

I wouldn't have made this such a big issue had you not claimed the
implementation didn't do what was requested, when both that and your
suggestion implements the request.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >>From: "Gennaro Prota" <[EMAIL PROTECTED]>
> >
> >> I'm happy that std::type_info has a private copy constructor. Hadn't
> >> it been for that, my suggestion to use just a couple of typedefs would
> >> have been routinely rejected :-)
> >
> > Storing a couple of type members is not enough, by itself. How would a
> > catch-clause taking e.g. a reference to bad_lexical_cast access them? To
> > access the typedefs, you need to know the exact type thrown, which means
you
> > need to know the types to begin with...
>
> There's absolutely no reason I can see to make the exact exception
> type depend on the types concerned.  Just use a straightforward
> class, something along the lines of:
>
>  struct bad_lexical_cast : std::exception
>  {
> bad_lexical_cast(
>std::type_info const& src, std::type_info const& dst)
>  : m_src(src), m_dst(dst) {}
> char const* what() throw() { return "bad_lexical_cast"; }
>
> std::type_info const& src() const { return m_src; }
> std::type_info const& dst() const { return m_dst; }
>   private:
> std::type_info const& src;
> std::type_info const& dst;
>  };

Right. I see that Kevlin also suggest this approach in a later posting. The
original version of the extended exception used static initialisation, as
mentioned, which is why it was templated.

I think this is a good approach.

Regarding the other MSVC 6 warning given in the original report, Gennaro
Prota has suggested using an explicit "!=", rather than relying on the
implicit conversion from pointer to bool. This also avoids using a cast,
instead.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> Terje Slettebø <[EMAIL PROTECTED]> writes:
> >>
> >> > I've tried the program below on Intel C++ 7.0 and MSVC 6, and I
haven't got
> >> > it to call terminate(). It may be that it doesn't handle exceptions
> >> > correctly, though.
> >>
> >> Because you are not running in a low-memory condition.
> >
> > What difference would that make? In the example program, it throws an
> > exception from the exception constructor, effectively simulating an
> > out-of-memory exception.
>
> Replace operator new so that it throws unconditionally *after* the
> exception object is constructed.  If you try this on an implementation
> where the exception object gets copied during unwinding, it will
> terminate().  It's the copy ctor that matters in this case.

The test program also had a throwing copy constructor. However, on Intel C++
7.0, the copy was elided, so the copy didn't get tested.

> >> > As it stands, it prints "Exception - Constructor", as it throws
> >> > an exception in the constructor of the Exception exception. If
> >> > the throw-statement in the constructor is commented out, it
> >> > prints "Exception - Exception", apparently not invoking the copy
> >> > constructor when throwing the exception (which it's allowed to).
> >>
> >> Irrelevant.  A program that invokes undefined behavior may appear to
> >> work fine also.

I did not state the latter part as a general claim, which is why I said that
eliding the copy is something it's allowed to, but not required to. Thus,
there's no argument to consider "irrelevant".

> >> >> What's wrong with char const*?
> >> >
> >> > You mean storing the string as a character array?
> >>
> >> No, I mean not storing the string at all (char const* is not an
> >> array), but storing an array is another option.
> >
> > Yes, I know that, of course. However, since if you just store a
> > pointer, the string has to be allocated some other way. How would
> > you allocate it?
>
> Just use a string literal; the compiler has to allocate that as part
> of the program image.

Sure, that's what the original lexical_cast did. However, if you are to
include in the string info about the types, storing it as a string literal
is not enough.

> > As Kevlin says in another posting, the "terminate on second
> > exception",
>
> He never used that phrase.  What do you mean?

True. I was referring to "In an insufficient-memory condition the former
will result in a bad_alloc being thrown and in the latter a call to
terminate." In other words, if you throw an exception in the copy
constructor, when an exception has already been thrown, i.e. during stack
unwinding, as you also say in the updated "Error and Exception Handling"
document.

> > which I thought you alluded to in your first reply, and maybe you
> > did, may not apply at the point of construction, since it only
> > applies after the evaluation of the throw-expression. In other
> > words, if the construction fails, you only loose the first
> > exception, and it instead throws the new one.
>
> I am aware of how C++ EH works, really!

I know you are. This was mostly to try to get a common understanding, since
I was a little confused about what you meant, and therefore wrote the above,
explaining what I had meant.

> > The reason the extended error type was added, was that there has
> > been requests on this list for storing the types used in the
> > conversion, in the exception, to make it easier to know which
> > conversion failed.
>
> That's a good request, but you didn't do that, did you?

Let me rephrase it: IIRC, the request was for storing information about the
types used, not how this was to be done. Thus, whether or not this does what
was requested depends on how to interpret the request.

The suggestion to store (pointer/reference to) type_info objects doesn't
store the types, either; it stores information about them, this time in a
way easier for the program to use.

So, I can just as well say as you say: The suggestion you said you meant
(storing references to type_info objects) doesn't do that, either, does it?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "Gennaro Prota" <[EMAIL PROTECTED]>

> On Sat, 22 Mar 2003 09:52:07 -0500, David Abrahams
> <[EMAIL PROTECTED]> wrote:
>
> >Kevlin Henney <[EMAIL PROTECTED]> writes:
>
> >> However, the decision as to whether this should be in the 'what' string
> >> is perhaps one that can be revisited. It would be feasible to avoid any
> >> allocation issues at all by leaving the human readable string as
general
> >> as it was before and adding type_info members that described the source
> >> and target types.
> >
> >Yes, that was my suggestion.
>
> I'm happy that std::type_info has a private copy constructor. Hadn't
> it been for that, my suggestion to use just a couple of typedefs would
> have been routinely rejected :-)

Storing a couple of type members is not enough, by itself. How would a
catch-clause taking e.g. a reference to bad_lexical_cast access them? To
access the typedefs, you need to know the exact type thrown, which means you
need to know the types to begin with...

I don't understand how this relates to private copy constructor, though,
could you explain?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "Kevlin Henney" <[EMAIL PROTECTED]>

> In message <[EMAIL PROTECTED]>, David Abrahams
> <[EMAIL PROTECTED]> writes
> >
> >There's no guarantee you have readable names anyway.
>
> That's a purely theoretical rather than practical consideration. In
> practice, I believe that all of the compilers that lexical_cast works
> under offer something relatively meaningful. The original version of
> lexical_cast simply stated, with a string literal, that the conversion
> had failed. There was some user demand for supplementary information,
> which Terje's version provided.
>
> However, the decision as to whether this should be in the 'what' string
> is perhaps one that can be revisited.

Indeed. :)

I wasn't sure what kind of interface to use for this, so I just made it part
of the what() string.

> It would be feasible to avoid any
> allocation issues at all by leaving the human readable string as general
> as it was before and adding type_info members that described the source
> and target types.

Yes. Since type_info objects can't be copied, one might instead store
pointers or references to them. This appears to need yet another inheritance
layer, though, unless the virtual functions for accessing the type_info
objects are made part of bad_lexical_cast. For example:

// exception used to indicate runtime lexical_cast failure
class bad_lexical_cast : public std::bad_cast
{
public:
virtual const std::type_info &source_type() const throw() = 0;
virtual const std::type_info &target_type() const throw() = 0;

virtual ~bad_lexical_cast() throw()
{
}
};

namespace detail // actual underlying concrete exception type
{
template
class no_lexical_conversion : public bad_lexical_cast
{
public:
virtual const std::type_info &source_type() const throw() {
return typeid(Source); }
virtual const std::type_info &target_type() const throw() {
return typeid(Target); }

virtual ~no_lexical_conversion() throw()
{
}
virtual const char *what() const throw()
{
return "bad lexical cast: "
   "source type value could not be interpreted as
target"
}
};
}

This also addresses the concern of readable type names, and leaves the
what() string as it was.

> This leads to a number of possible options:
>
> (1) Use the static solution, as Terje originally intended, and use the
> current solution only for VC6.
> (2) Rollback the design to something closer to the original, ie a fixed-
> string literal message as the result of calling 'what', and provide
> supplementary information for handlers that care enough to catch a
> bad_lexical_cast.

I think this is a good solution, and it eliminates any throws from the
exception. This may also be a more flexible solution, as the type_info
objects may be used directly, in any custom error message.

> (3) Play around with C-style memory management and allocate arrays on
> demand, being sure to trap any bad outcome.
> (4) Leave as is.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >>From: "David Abrahams" <[EMAIL PROTECTED]>
> >
> >> Terje Slettebø <[EMAIL PROTECTED]> writes:
> >>
> >> >> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) :
> > warning
> >> > C4512: 'no_lexical_conversion >> > std::char_traits,class std::allocator >,long>' :
assignment
> >> > operator could not be generated
> >> >
> >> > This is due to that it stores a const std::string object, describing
the
> >> > exception
> >>
> >> Are you saying that you have defined an exception with a std::string
> >> member?  That's VERY bad!  Throwing that exception can lead directly
> >> to termination!
> >
> > You mean if the exception itself throws during construction or copying?
>
> Yes.
>
> > I've tried the program below on Intel C++ 7.0 and MSVC 6, and I haven't
got
> > it to call terminate(). It may be that it doesn't handle exceptions
> > correctly, though.
>
> Because you are not running in a low-memory condition.

What difference would that make? In the example program, it throws an
exception from the exception constructor, effectively simulating an
out-of-memory exception.

> > As it stands, it prints "Exception - Constructor", as it throws an
exception
> > in the constructor of the Exception exception. If the throw-statement in
the
> > constructor is commented out, it prints "Exception - Exception",
apparently
> > not invoking the copy constructor when throwing the exception (which
it's
> > allowed to).
>
> Irrelevant.  A program that invokes undefined behavior may appear to
> work fine also.

You said that it may terminate the program. I assumed from that that you
meant it would call terminate(). Did you instead mean undefined behaviour?
If so, how? And how would that be related to terminating the program? As you
say, anything can happen with undefined behaviour, including the "expected"
behaviour.

> >> What's wrong with char const*?
> >
> > You mean storing the string as a character array?
>
> No, I mean not storing the string at all (char const* is not an
> array), but storing an array is another option.

Yes, I know that, of course. However, since if you just store a pointer, the
string has to be allocated some other way. How would you allocate it? If you
use "new", won't that bring the same potential problem as std::string? This
is why I thought you might have meant storing an array (as STLPort does it),
rather than storing a pointer. Storing an array eliminates the possibility
of throwing an exception at construction.

> > Sure, that's possible, and I see that STLPort do it, and it's
> > probably safer, as you say. It does mean you have to specify the
> > maximum string length in advance, though. As "no_lexical_conversion"
> > what() prints out the source and target types, it may truncate long
> > type names.
>
> There's no guarantee you have readable names anyway.  Finally, you
> should never format exception messages at the throw point.  An
> exception whose what() needs to print type names should store the
> typeids and put the formatting logic in what().

A problem is that what() can't throw, either. So you'd have to wrap it in a
try-catch. Then there's the issue of what to return from what() if the
formatting throws.

As Kevlin says in another posting, the "terminate on second exception",
which I thought you alluded to in your first reply, and maybe you did, may
not apply at the point of construction, since it only applies after the
evaluation of the throw-expression. In other words, if the construction
fails, you only loose the first exception, and it instead throws the new
one.

As for throwing in the copy constructor, that might be a problem, since the
"call by value" semantics of throwing an exception may mean that it makes a
copy of the exception, after the throw-expression is evaluated.

The reason the extended error type was added, was that there has been
requests on this list for storing the types used in the conversion, in the
exception, to make it easier to know which conversion failed. It has also
proved useful in the regression testing. bad_lexical_cast was not modified,
to not break the interface, so this type inherits from it.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-21 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) :
warning
> > C4512: 'no_lexical_conversion > std::char_traits,class std::allocator >,long>' : assignment
> > operator could not be generated
> >
> > This is due to that it stores a const std::string object, describing the
> > exception
>
> Are you saying that you have defined an exception with a std::string
> member?  That's VERY bad!  Throwing that exception can lead directly
> to termination!

You mean if the exception itself throws during construction or copying?

I've tried the program below on Intel C++ 7.0 and MSVC 6, and I haven't got
it to call terminate(). It may be that it doesn't handle exceptions
correctly, though.

#include 
#include 
#include 

class Exception : public std::runtime_error
{
public:
  Exception() : std::runtime_error("Exception")
{ throw std::runtime_error("Construction"); }

  Exception(const Exception &) : std::runtime_error("Exception (copied)")
{ throw std::runtime_error("Copy"); }
};

int main()
{
  try
  {
throw Exception();
  }
  catch(const std::exception &e)
  {
std::cout << "Exception - " << e.what() << '\n';
  }
  catch(...)
  {
std::cout << "Unknown exception\n";
  }
}

As it stands, it prints "Exception - Constructor", as it throws an exception
in the constructor of the Exception exception. If the throw-statement in the
constructor is commented out, it prints "Exception - Exception", apparently
not invoking the copy constructor when throwing the exception (which it's
allowed to).

> What's wrong with char const*?

You mean storing the string as a character array? Sure, that's possible, and
I see that STLPort do it, and it's probably safer, as you say. It does mean
you have to specify the maximum string length in advance, though. As
"no_lexical_conversion" what() prints out the source and target types, it
may truncate long type names.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-21 Thread Terje Slettebø
>From: "John Swartzentruber" <[EMAIL PROTECTED]>

> I downloaded 1.30.0 and tried to build my project. I got a few errors
> that seem to be in boost, primarily in lexical_cast. Also,
> weak_ptr.hpp uses bad_weak_ptr without including
> boost/detail/shared_count.hpp anywhere. I can fix that by
> including it in my code.
>
> These are the warnings in lexical_cast.hpp. Because I treat
> warnings as errors, these pretty much keep me from using this
> version of boost.

In the reported output there are two warnings, both level 4 warnings, which
are more or less remarks. That's why they are disabled in the lexical_cast
unit tests. They are:

> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning
C4512: 'no_lexical_conversion,class std::allocator >,long>' : assignment
operator could not be generated

This is due to that it stores a const std::string object, describing the
exception. "no_lexical_cast" is the concrete exception type returned, and it
inherits from "bad_lexical_cast". The reason it stores a string object,
rather than using a static string member (since the information is the same
for all objects of it), is that MSVC 6 couldn't handle that static
initialisation. Ironic, huh? :)

A simple way to fix this is to make the string object non-const, although
there's really no reason for it to be assigned to, as all objects are the
same.

> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(147) : warning
C4800: 'void *' : forcing value to bool 'true' or 'false' (performance
warning)
> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(146) :
while compiling class-template member function 'bool __thiscall

This uses the implicit conversion from pointer to bool, and one could
probably avoid the warning with an explicit cast.

An alternative to the above is:

#pragma warning(disable: 4512 4800)

:)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Win32/VC++ 6.0 lexical_cast problems

2003-03-19 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> At 03:13 AM 3/19/2003, Terje Slettebø wrote:
>
>  >Ok, it seems we may have to exclude wide character support for
> lexical_cast
>  >on MSVC 6, to avoid breaking Date/Time. I suggest something like:
>  >
>  >#if defined(BOOST_NO_STRINGSTREAM) || \
>  >defined(BOOST_NO_STD_WSTRING) || \
>  >defined(BOOST_NO_STD_LOCALE) || \
>  >defined(BOOST_NO_CWCHAR) || \
>  >defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)
>  >#define DISABLE_WIDE_CHAR_SUPPORT
>  >#endif
>
> OK, the full Win32 tests are posted. The date-time tests are now passing.
>
> lexical_cast_test itself is failing for VC++ 6.0. See below.

I see from the CVS that the above has only been put in the header, not the
test, as well. It needs to be in both. If it's just in the header, it'll try
the wide character tests - on a header that has wide character conversions
disabled - a recipe for disaster. ;)

I've tried the above for both the header and test on MSVC 6.5, and it passes
with no errors here, 82/137 tests (the rest are omitted by the above test).

I've done the above changes on the lexical_cast test, and committed it to
both the trunk and 1.30.

The last item on my "checklist" posted earlier was to remove the
BOOST_WORKAROUND's (which used to be for MSVC 6 and g++ 2.95), as they are
not needed, and I did that, as well, before running the test.

Also, since the regression tests doesn't test for g++ 2.95, on Windows, I
guess there's no need to set "expected failures" for that compiler, after
all. It works without errors on g++ 3.2.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-19 Thread Terje Slettebø
>From: "Kevlin Henney" <[EMAIL PROTECTED]>

> In article <[EMAIL PROTECTED]>, Terje Slettebø
> <[EMAIL PROTECTED]> writes
> >
> >However, the three failing tests for each of MSVC 6 and g++ 2.95
(different
> >ones for the two) are in the middle of some wide character tests.
>
> My original intent was to disable wide character support for any
> platform that was effectively less than 99% conforming in its support
> for wide characters, including non-intrinsic wchar_t. So g++ 2.95 and
> MSVC 6 should not, strictly speaking, offer any support for wide
> character conversions out of the box.

Using John's suggestion, it now correctly disables wide character support
for g++ 2.95, so the three failing tests that Genny reported (and which I
posted) are unrelated to wide characters. To deal with them, one may set
"expected failures", as Gennadiy suggested.

For MSVC 6, in my last posting, I posted a patch to disable wide characters
for MSVC 6, as well. That takes care of the three other test failures on
that compiler, since they were related to wide characters.

So in summary, one may do:

- Remove all BOOST_WORKAROUND's (for MSVC 6 and g++, they are not needed
anymore for the former, and for the latter, "expected failures" is used)
- Set expected failures to 3 for g++ 2.95
- Disable wide character support for MSVC 6, using the patch I gave:

#if defined(BOOST_NO_STRINGSTREAM) || \
defined(BOOST_NO_STD_WSTRING) || \
defined(BOOST_NO_STD_LOCALE) || \
defined(BOOST_NO_CWCHAR) || \
defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif

- Run regression tests, and if ok, ship Boost. :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-19 Thread Terje Slettebø
>From: "Gennadiy Rozental" <[EMAIL PROTECTED]>

> > > > Notice the weird misspellings in the error messages. :)
> > >
> > > What do you mean?
> >
> > "boolle" and "intr"? :)
> >
> > Could this be a problem in the unit test framework?
> 
> Could be. What should it be?

They should be:

test_conversion_to_bool();
test_conversion_to_int();


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Win32/VC++ 6.0 lexical_cast problems

2003-03-19 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> A fresh version of the Win32 regression tests has just been posted. See
> http://boost.sourceforge.net/regression-logs/cs-win32-RC_1_30_0-diff.html
>
> There are seven new fails in date_time tests; presumably all caused by
> lexical_cast.hpp problems. See typical error message below.

I see that all of the new failing tests are on MSVC 6, and it seems the
errors is due to allowing wide character support on MSVC 6. In the Date/Time
tests there are calls such as lexical_cast(),
which lexical_cast on MSVC 6 interprets as trying to convert from
std::string to wchar_t. This also fails in the lexical_cast unit test for
MSVC 6.

Ok, it seems we may have to exclude wide character support for lexical_cast
on MSVC 6, to avoid breaking Date/Time. I suggest something like:

#if defined(BOOST_NO_STRINGSTREAM) || \
defined(BOOST_NO_STD_WSTRING) || \
defined(BOOST_NO_STD_LOCALE) || \
defined(BOOST_NO_CWCHAR) || \
defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif

(Testing for BOOST_NO_INTRINSIC_WCHAR_T, instead, would also disable wide
character support on Intel C++ (on Windows), which does work with
lexical_cast)

I've tested this with Date/Time's testclock.cpp (one of the failing tests)
on MSVC 6 and Intel C++ 7, and it now works.

On the plus side, it appears to now work on g++ 2.95.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> >From: "Rozental, Gennadiy" <[EMAIL PROTECTED]>
>
> > > If these are omitted for g++ 2.95.x, all tests pass for that compiler.
> > > However, as it compiles without errors on both MSVC 6 and g++
> > > 2.95.x, maybe
> > > one shouldn't have any BOOST_WORKAROUND's in the test code?
> > >
> > > That will make it show up as failing on MSVC 6 and g++
> > > 2.95.x, even though
> > > it passes almost all the enabled tests on both.
> >
> > You could use expected failures feature of Boost.Test
>
> Aha. That could be an odd test, though

Sorry, I misunderstood. I thought it was testing for failure, when I
realised that "expected failures" is something else, in the framework. Yes,
using it could be a possibility. It seems just right for the task.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> > Also these three tests, like MSVC 6, concerns tests where it doesn't
throw
> > when it's supposed to:
> >
> > BOOST_CHECK_THROW(lexical_cast(" 123"), boost::bad_lexical_cast);
> > BOOST_CHECK_THROW(lexical_cast(std::string(" 123")),
> > boost::bad_lexical_cast);
> > BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast);
> >
> > If these are omitted for g++ 2.95.x, all tests pass for that compiler.
> > However, as it compiles without errors on both MSVC 6 and g++ 2.95.x,
maybe
> > one shouldn't have any BOOST_WORKAROUND's in the test code?
> >
> > That will make it show up as failing on MSVC 6 and g++ 2.95.x, even
though
> > it passes almost all the enabled tests on both.
>
> Often the cure is to break the test into two parts, so that you can
> demonstrate passing the majority of tests even on broken compilers.

Yeah. That's what is done with the 10 tests making up the suite - 6 for char
and 4 for wide character.

However, the three failing tests for each of MSVC 6 and g++ 2.95 (different
ones for the two) are in the middle of some wide character tests.

As Beman also points out, what is most important is that lexical_cast
doesn't cause other components to fail, even if they don't use an
unsupported feature. Therefore, to not mask any run-time errors on MSVC 6
and g++ 2.95, one may remove the BOOST_WORKAROUND's, since the failing tests
don't appear to have much in common.

Anyway, now that you've has committed it, we'll see how it goes in the
regression test. At least BOOST_TESTED_AT should be taken out before the
release, as you said.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "Kevlin Henney" <[EMAIL PROTECTED]>

> Close inspection reveals that the config file
> studiously avoids accommodating g++ 2.95:
>
> #if defined(__GNUC__) && (__GNUC__ < 3) && \
>  ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \
>  !defined(__STL_USE_NEW_IOSTREAMS) || \
>defined(__APPLE_CC__)
>// Note that we only set this for GNU C++ prior to 2.95 since the
>// latest patches for that release do contain a minimal 
>// If you are running a 2.95 release prior to 2.95.3 then this will
> need
>// setting, but there is no way to detect that automatically (other
>// than by running the configure script).
>// Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't
>// have .
> #  define BOOST_NO_STRINGSTREAM
>
> #endif
>
> In other words, lexical_cast will work if the instructions in the config
> file are followed. According to the config file anyone running 2.95 is
> in effect on their own. Terje's changes should be applied: any remaining
> g++ 2.95 problems would then be down to local config and rather than
> lexical_cast.hpp to address.

Also, John's suggestion (incorporated in the posted version) means that it
doesn't rely on BOOST_NO_STRINGSTREAM being set, to work on g++ 2.95.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "Rozental, Gennadiy" <[EMAIL PROTECTED]>


> > lexical_cast_test.cpp(105): error in
> > "test_conversion_to_intr": exception
> > boost::bad_lexical_cast is expected
> > lexical_cast_test.cpp(111): error in
> > "test_conversion_to_intr": exception
> > boost::bad_lexical_cast is expected
> > lexical_cast_test.cpp(147): error in
> > "test_conversion_to_boolle": exception
> > boost::bad_lexical_cast is expected
> >
> > Notice the weird misspellings in the error messages. :)
>
> What do you mean?

"boolle" and "intr"? :)

Could this be a problem in the unit test framework?

> > Also these three tests, like MSVC 6, concerns tests where it
> > doesn't throw
> > when it's supposed to:
> >
> > BOOST_CHECK_THROW(lexical_cast(" 123"), boost::bad_lexical_cast);
> > BOOST_CHECK_THROW(lexical_cast(std::string(" 123")),
> > boost::bad_lexical_cast);
> > BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast);
> >
> > If these are omitted for g++ 2.95.x, all tests pass for that compiler.
> > However, as it compiles without errors on both MSVC 6 and g++
> > 2.95.x, maybe
> > one shouldn't have any BOOST_WORKAROUND's in the test code?
> >
> > That will make it show up as failing on MSVC 6 and g++
> > 2.95.x, even though
> > it passes almost all the enabled tests on both.
>
> You could use expected failures feature of Boost.Test

Aha. That could be an odd test, though: Ensuring that a bug is there. :) One
thing is to test for something that is supposed to fail, or throw an
exception, on a conforming compiler. However, using the same mechanism to
make tests pass, which are really failing, seems like a strange use of that
feature.

It isn't clear to me that this improves the situation over BOOST_WORKAROUND,
and may instead obfuscate it, as someone reading the code might not know
whether a fail-test is to test conformance, or to allow a bug.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> > - With wide character support in lexical_cast enabled for MSVC 6, three
> > tests (of 137) fail. These are omitted for that compiler version, using
> > BOOST_WORKAROUND and BOOST_TESTED_AT.
>
> You shouldn't be using BOOST_TESTED_AT for that compiler, since there
> are known newer versions
>
> BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
>
> is the right test.

Right. Reading the docs in workaround.hpp, again, I see that now. I'll
change it.

> (unless of course it fails for those too).

No, it passes all tests on MSVC 7.

Also, I've just now got a mail from Gennaro Prota. He has tested the posted
version on g++ 2.95.3-10 (Cygwin). The test correctly disable wide character
support, and passed except for three cases:

lexical_cast_test.cpp(105): error in "test_conversion_to_intr": exception
boost::bad_lexical_cast is expected
lexical_cast_test.cpp(111): error in "test_conversion_to_intr": exception
boost::bad_lexical_cast is expected
lexical_cast_test.cpp(147): error in "test_conversion_to_boolle": exception
boost::bad_lexical_cast is expected

Notice the weird misspellings in the error messages. :)

Also these three tests, like MSVC 6, concerns tests where it doesn't throw
when it's supposed to:

BOOST_CHECK_THROW(lexical_cast(" 123"), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast(std::string(" 123")),
boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast);

If these are omitted for g++ 2.95.x, all tests pass for that compiler.
However, as it compiles without errors on both MSVC 6 and g++ 2.95.x, maybe
one shouldn't have any BOOST_WORKAROUND's in the test code?

That will make it show up as failing on MSVC 6 and g++ 2.95.x, even though
it passes almost all the enabled tests on both.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-18 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> My patience has been exhausted. The folks that care about configuring
> lexical_cast for GCC 2.95.3 with the SGI library need come forward
> immediately and tell us how to deal with this, or 1.30.0 will ship as is.

I've applied John Maddock's suggestion to my local copy of the version in
CVS, and ran some tests. Preliminary results are good, and are listed at the
end, here.

I've tested it on Intel C++ 7.0, MSVC 6, and g++ 3.2 (MinGW). Could somebody
test the attached files on g++ 2.95.x? Genny?

There are also some other changes, and I list them below. The current
version in the CVS is very restrictive with wide character support, meaning
you can't use it with wide characters on platforms that would otherwise be
able to handle it. This includes Intel C++ 7.0 (on Windows) and MSVC 6.

The restriction was done to remedy the failing regression tests. However,
with John's suggestion, you get a pass _and_ wide character support for
those platforms that can handle it, regardless of whether they have
intrinsic wchar_t.

The changes are
---
- Changed "#include " to "#include
", as it's the only trait used. This
removes a lot of includes, and therefore dependencies with the type traits.
Kevlin has agreed to this suggestion.

- Removed duplicate tests. Since tests for "const char *" and "char *" for
source were merged to just using string literal for source, some tests ended
up as duplicates. These duplicates have been removed, bringing the number of
tests down from 171 to 137. This is also agreed to by Kevlin.

- With wide character support in lexical_cast enabled for MSVC 6, three
tests (of 137) fail. These are omitted for that compiler version, using
BOOST_WORKAROUND and BOOST_TESTED_AT.

They failing tests are related to that wchar_t is a typedef for unsigned
short on MSVC 6. They are:

BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast(std::wstring(L"Test")),
boost::bad_lexical_cast);

Test results for the attached files

Intel C++ 7.0 (strict mode, intrinsic wchar_t enabled) - 137/137 passes
MSVC 6 (no intrinsic wchar_t)   -
134/137 passes (3/137 omitted, the ones above, or they would fail)
g++ 3.2 (MinGW) (Not proper wide character support) - 82/137 (the rest
omitted by the wide character disabling)

As mentioned, with the current version in CVS, Intel C++ 7.0 and MSVC 6 only
gets pass on about half of total tests, since wide character support is
disabled in lexical_cast for them, even though, as shown above, they handle
it very well.

However, not at least, it's a question of whether this version fares better
on g++ 2.95.x.


Regards,

Terje


lexical_cast_test.cpp
Description: Binary data


lexical_cast.hpp
Description: Binary data
___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-17 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> At 03:40 PM 3/17/2003, Terje Slettebø wrote:
>
>  >Well, I think this reinforces the suggestion to define
>  >BOOST_NO_STRINGSTREAM
>  >for 2.95.x. Comments?
>  >
>  >Either that, or to have some way to detect where
> std::basic_stringstream<>
>  >is not supported, and turn off wide character support for that, in
>  >lexical_cast. Currently, it disables wide character support if one of
the
>  >following macros are set:
>  >
>  >BOOST_NO_STRINGSTREAM
>  >BOOST_NO_STD_WSTRING
>  >BOOST_NO_INTRINSIC_WCHAR_T
>
> Are you sure disabling wide character support is really the solution, or
> that it is really fully disabled?

Well, as was shown with the earlier lexical_cast, g++ 2.95 does have
std::stringstream, but not std::basic_stringstream. This shows that even if
it has stringstream, it doesn't have the wide character version of it. This
means it can't be used with wide characters with lexical_cast. So this has
to be signalled somehow to lexical_cast. Any macro might do, but as it has
only partial stringstream support, defining BOOST_NO_STRINGSTREAM seems
reasonable. An alternative is to create a macro for partial support, but the
end result is the same for lexical_cast: No wide character support for that
compiler version.

> For the 2.95.x test at
>
http://boost.sourceforge.net/regression-logs/cs-linux-RC_1_30_0-links.html#c
onfig_info%20gcc2953,
> BOOST_NO_STD_WSTRING is already defined, so presumably wide character
> support is already disabled.
>
> Look at the error messages from date_time testperiod below, and the source
> code lines they refer to. At least directly, they don't seem releated to
> wide character support.
>
> /home/boost/boost-regress-RC_1_30_0/boost/boost/lexical_cast.hpp:173:
> syntax error before `;'

Line 173 has:

std::basic_stringstream stream;

I think the evidence can't be much clearer. :)

The rest appears to be cascading errors, but this is the first reported one.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-17 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> > typedef std::vector vector_char;
> >
> > vector_char values;
> >
> > // Fill with 'A', 'B', 'C'
> >
> > std::cout << io::format("[", "]", ", ", "\'", "\'") <<
values;
> >
> > Output:
> >
> > ['A', 'B', 'C']
> >
> > However, is this overkill?
>
>  It seems that way, especially considering that if it was a vector of
> anything other than a fundamental type with std::cout << already defined
> for it, you could add a second io::format("\'","\'","") and it
> would work.

Right. However, I've already implemented it, anyway, as an experimental
feature. :) Besides, the two extra strings default to empty strings.

> > Feedback is most welcome.
>
>   Would possibly a function object for outputting the contained item be
> better?

[I first thought you meant a function object for outputting the _container_,
not the elements, so I wrote the following section, before realising that
you had meant for the elements. I address it afterwards]

I've been thinking of the same, with regard to outputting the _container_
(not the element, itself). In an earlier posting, I mentioned the
possibility of using function objects, as a way to generalising the handling
of output. I also mentioned having the kind of function objects like BGL,
i.e. "visitors". That is, rather than only overloading the operator(), it
may provide several member functions, e.g.:

class stream_visitor
{
public:
  void start();
  void end();
  void delimiter();
};

std::cout << format(stream_visitor(...));

One could then provide a function object which does what it currently does.

There are issues with this, however. I've been thinking long and hard about
how to provide this functionality. The issue is that the functors has to be
stored somewhere, and being accessible. With the current version, all the
format objects are the same type, so you know its type when it's stored and
retrieved. However, if arbitrary (generic) functors are stored, you don't
know its type, when you access it, when performing output. It's similar to
trying to store different types in the same std::vector.

There are solutions to this, and one is to use a common interface, and all
functors inherit from that interface, and override the virtual functions.
That would let you store them using a pointer to the interface. However,
this means the overhead of a virtual function call per call to the member
functions above. This may not be that much, but it's still also the issue
that generic functors can't be used - they all have to inherit from the same
interface.

For this reason, I found that this could be a possible later addition, if we
find that the added flexibility is worth it.

Also, the current syntax could still be kept as a convenience, by having an
overloaded constructor taking the strings, and creating the functor. So a
change may be backwards compatible.

> Here's a possibly mutilated example (I've never actually used
> function objects before):
>
> std::ostream delimitted_char(std::ostream out, char x, std::string
> first, std::string last);
>
> std::cout << io::format("[", "]", ", ",
>   bind("\'", 4, bind("\'", 3, delimitted_char)))

Yes, it's possible, but I this seems to make it more complex than simply
using io::format("[", "]", ",", "\'", "\'"), with the two last
strings defaulted to empty strings.

> > There's yet another alternative way this may be done, using
"placeholder"
> > types, i.e.:
> >
> > std::cout << io::format >(...); // Sets the format for
all
> > vectors
> > std::cout << io::format<_>(...); // Sets the format for all types
(defaults)
> >
> > This would avoid hardcoding any defaults, as the user could change it.
> >
> > The output routines could then check the formats in the following order,
> > e.g. for "std::vector":
> >
> > If there's a format set for std::vector, use it, else
> > if there's a format set for std::vector<_> (all vectors), use it, else
> > use format for _.
> >
> > Comments?
>
> I like it :)

I found it quite neat, as well. :) Interestingly, one important contribution
of libraries are concepts and idioms. Since "_" is used as placeholder other
places, making it mean "any type" here is reasonably intuitive, as well.

> Using just _ scares me a bit... It would 

Re: [boost] Re: RC_1_30_0 still broken -- More lexical_cast

2003-03-17 Thread Terje Slettebø
>From: "Gennaro Prota" <[EMAIL PROTECTED]>

> On Mon, 17 Mar 2003 14:47:20 +0300, Vladimir Prus <[EMAIL PROTECTED]>
> wrote:
>
> >Gennaro Prota wrote:
> >
> >>>Ok. I've forwarded this to Kevlin.
> >>
> >> Maybe there's more than one problem here. I see that Vladimir talks
> >> about warnings while Jeff about errors. Also maybe it helps to see the
> >> exact condition to define BOOST_NO_STRINGSTREAM in
> >> config/stdlib/sgi.hpp, with the comment therein? Just trying to lend a
> >> hand...
> >
> >I'm sorry, "warning" in my post is typo. It should have been "error", and
> >the error message is precisely the same as previously reported. I just
> >wanted to note that lexical_cast was not broken with gcc 2.95.4 until
> >recently.
>
> Ok. That compiler has always used the new  header. I think
> the problem is that while the old lexical_cast just used
> std::stringstream the new version uses the more general
> std::basic_stringstream<>.

Aha. I think this may be the key. Thanks a lot. :) I was really wondering
what the heck was different. :)

Well, I think this reinforces the suggestion to define BOOST_NO_STRINGSTREAM
for 2.95.x. Comments?

Either that, or to have some way to detect where std::basic_stringstream<>
is not supported, and turn off wide character support for that, in
lexical_cast. Currently, it disables wide character support if one of the
following macros are set:

BOOST_NO_STRINGSTREAM
BOOST_NO_STD_WSTRING
BOOST_NO_INTRINSIC_WCHAR_T

even though it may work partially or fully with wide characters, despite one
of these set. For example, Intel C++ 7.0 on Windows has intrinsic wchar_t,
and passes all the lexical_cast tests, but as the intrinsic characters have
to be turned on with a switch (for compatibility with MSVC 6/7), and there
appears to be no macro to detect the switch, the config sets
BOOST_NO_INTRINSIC_WCHAR_T.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] RC_1_30_0 still broken -- More lexical_cast

2003-03-17 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > > /home/boost/boost-regress/boost/boost/lexical_cast.hpp:173: syntax
error
> > > before `;'
> >
> > Looking at the CVS, it appears the reason for this is that
> > config/compiler/gcc.hpp no longer defines BOOST_NO_STRINGSTREAM, even
> > though it should, at least for 2.95.x and below, as is shown with the
above
> > errors..
> >
> > The change was done about a year ago, though, so it appears lexical_cast
> > hasn't been working on g++ 2.95.x for a long time.
>
> I don't have much to say, but lexical_cast was broken just now. My  code
which
> was compiling a week ago and wasn't changed since now produces the same
> warning, after updating to RC_1_30_0.

Ok. I've forwarded this to Kevlin.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] RC_1_30_0 still broken -- More lexical_cast

2003-03-16 Thread Terje Slettebø
>From: "Jeff Garland" <[EMAIL PROTECTED]>

> On Sun, 16 Mar 2003 17:34:18 -0500, Beman Dawes wrote
> > I'll go over the do-list again after dinner, but it looks like
> > almost all problems have been cleared except for this one.
>
> I don't know if the Linux results are up to date, but
> it appears that we have still taken a step backward with
> lexical cast on gcc 2.95.3.  This is causing a large number
> date_time tests which compiled and executed correctly with
> the 1.29 release to fail.
>
> Without actually looking at the source it would be my
> guess that this is related to the fact that the 2.95.3
> standard library only supported old iostreams and that
> somehow the lexical_cast work around got lost in the
> changes.  This is supported by the fact that the same
> tests work fine with STLPort.  It would be nice if this
> workaround could be restored before the release even if
> results in the 2.95.3 version having the 'string' bug.
> I've attached the details for reference...
>
> Jeff
>
> In file included from
> /home/boost/boost-regress/boost/boost/date_time/date_parsing.hpp:10,
>  from
> /home/boost/boost-regress/boost/boost/date_time/gregorian/parsers.hpp:9,
>  from
>
/home/boost/boost-regress/boost/boost/date_time/gregorian/gregorian.hpp:17,
>  from ../libs/date_time/test/gregorian/testdate.cpp:7:
> /home/boost/boost-regress/boost/boost/lexical_cast.hpp:173: syntax error
> before `;'

Looking at the CVS, it appears the reason for this is that
config/compiler/gcc.hpp no longer defines BOOST_NO_STRINGSTREAM, even though
it should, at least for 2.95.x and below, as is shown with the above
errors..

The change was done about a year ago, though, so it appears lexical_cast
hasn't been working on g++ 2.95.x for a long time.

In other words, the problem isn't in lexical_cast but in the config files.
Could this be fixed? Also, shouldn't this be done in the library config, not
the compiler?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: Possible problem in integer_traits.hpp

2003-03-16 Thread Terje Slettebø
>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> When trying to use integer_traits on Intel C++ 7.0, I get the following
> error (main line and branch):
>
> boost/integer_traits.hpp(69): error: name followed by "::" must be a class
> or namespace name
>   public detail::integer_traits_base
>  ^
>
> This is the compiler's way of saying that "integer_traits_base" is not
known
> at this point.

Actually, it means that "detail" is not known, of course. However, the next
error says that "integer_traits_base" isn't known, either.

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Possible problem in integer_traits.hpp

2003-03-16 Thread Terje Slettebø
Hi.

When trying to use integer_traits on Intel C++ 7.0, I get the following
error (main line and branch):

boost/integer_traits.hpp(69): error: name followed by "::" must be a class
or namespace name
  public detail::integer_traits_base
 ^

This is the compiler's way of saying that "integer_traits_base" is not known
at this point.

The structure of the header is like this:

--- Start ---

namespace boost {
template
class integer_traits : public std::numeric_limits
// ...

namespace detail {
template
class integer_traits_base
// ...

} // namespace detail

template<>
class integer_traits
  : public std::numeric_limits,
public detail::integer_traits_base // Error here
{ };

} // namespace boost

--- end ---

When moving the detail namespace and integer_traits_base above the
definition of integer_traits, the error disappears.

Could it be that when specialising templates, it only looks up the names in
the context of the primary template, not the context of the specialisation?

If this is the case, could this be fixed?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-16 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >
> > std::vector > test;
> >
> > std::cout << test: // Using defaults
> >
> > (('A',1),('B',2),('C',3))
>
> I would suspect that chars don't get output with '' around them...
> Is there even a way to specify/change that?  Something similar for
> strings (along with an escape character) would be very handy for
> strings.

I've found a way this may be done. If you specify "start element" and "end
element" strings, in addition, it may be done. Currently, it takes "start
sequence", "end sequence", and "delimiter", so this would mean two
(optional) more. E.g.:

typedef std::vector vector_char;

vector_char values;

// Fill with 'A', 'B', 'C'

std::cout << io::format("[", "]", ", ", "\'", "\'") << values;

Output:

['A', 'B', 'C']

However, is this overkill?

Even if the last two are optional, it means the output routines have to
output (possibly empty) strings before and after each element, in addition
to the delimiter.

Feedback is most welcome.

> > There was a suggestion for allowing generic formats, though, using
> > the same format for all instantiations of a template. The question is
how to
> > do it. The current version stores the format for each specific type, as
you
> > say. Volodya suggested a couple of ways it could be done, partial
> > specialisation, or storing the template name in a map.

There's yet another alternative way this may be done, using "placeholder"
types, i.e.:

std::cout << io::format >(...); // Sets the format for all
vectors
std::cout << io::format<_>(...); // Sets the format for all types (defaults)

This would avoid hardcoding any defaults, as the user could change it.

The output routines could then check the formats in the following order,
e.g. for "std::vector":

If there's a format set for std::vector, use it, else
if there's a format set for std::vector<_> (all vectors), use it, else
use format for _.

Comments?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] CVS main line is all messed up

2003-03-14 Thread Terje Slettebø
>From: "Victor A. Wagner, Jr." <[EMAIL PROTECTED]>


> for the past 3 hours I've been getting:
> ...failed updating 300 targets...
> ...skipped 117 targets...
> ...updated 8 targets...
>
> when trying to make the latest CVS update:
> date /T >> update.log
> time /t >> update.log
> cvs -z3 update -A -P -d >> update.log
> bjam "-sTOOLS=vc7 msvc vc71" >bjam.log
> mgrep target bjam.log
>
> this also, of course, prevents me from chasing down why I got 12 missing
> functions when I tried to build  simple_ls.cpp.
>
> I started to take a look at what's causing the errors, but... I think I'll
> let the folks who checked in something they shouldn't find them.  One of
> the errors I see insists that "filesystem" isn't part of namespace
"boost".

Sorry, that may well have been me. I checked in an updated description in
is_base_and_derived.hpp (OK'ed by John Maddock), and it happened to contain:

"B1 const volatile*/B2 const volatile*"

which of course the compiler interpreted as ending the comment. Therefore it
gave an error on the rest. Any file including this header, or
type_traits.hpp (which includes it), would therefore fail.

I didn't run the tests on this one before committing, because I thought
changing a comment couldn't possibly break any tests. It's fixed now.

This goes for RC_1_30_0, as well.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: lexical_cast

2003-03-13 Thread Terje Slettebø
>From: "Kevlin Henney" <[EMAIL PROTECTED]>

> In article <[EMAIL PROTECTED]>, David Abrahams
> <[EMAIL PROTECTED]> writes
> >Kevlin Henney <[EMAIL PROTECTED]> writes:
> >
> >>>on deficient compilers.
> >>
> >> Agreed. However, VC7 is not such a compiler
> >
> >Huh?  VC7 not deficient?
>
> Perhaps that claim was too broad ;-)
>
> >It certainly doesn't support partial
> >ordering.
>
> True. But the ordering of definitions is such that it does work on VC7
> (swap them round and it doesn't work). The error message indicated did
> not seem to indicate that this was the problem.
>
> >most-confused-ly y'rs,
>
> In which case, it is clear that I must be imagining all the successful
> compilations and test executions I have been having.

No, you didn't; I got problem-free compilation of that version on VC7, too.
Let's just say that VC7's support for partial ordering is, uhm, partial. ;)

>From an earlier posting:

> From the compiler messages I am
> seeing, it is uncertain whether Terje's trial implementation would have
> faired uniformly better.

Since MSVC 6/7, and Borland C++, doesn't handle partial ordering of function
templates well, or not at all, I also had to avoid that for those platforms,
by having workaround code for them in my proposition. Just like you've had
to avoid partial ordering in your latest version, to make it work properly
on MSVC, especially version 6.

My proposition would likely have fared better than the first update that was
committed, due to the mentioned workaround code it had. However, since then,
you've got the new version to work with tests passing on all the compilers
on the Win32 tests, so it's at least as portable.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] RC_1_30_0: lexical_cast.hpp broken under Mac OS X/gcc3.2.2

2003-03-12 Thread Terje Slettebø
>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> The new
> version of lexical_cast is Kevlin's own, which he recently made, not my
> proposition. I think his version is better, though, as it's much shorter
and
> removes duplication.

Just to point out that it's the kind of duplication which is not easily
removed; the new version works differently. The proposition used several
overloaded function templates for the various special cases, whereas the new
version uses a trait technique. Another advantage of the new version is that
it doesn't require special workarounds for compilers lacking partial
ordering of function templates, which the proposition needed.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] RC_1_30_0: lexical_cast.hpp broken under Mac OS X/gcc3.2.2

2003-03-12 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> At 07:40 PM 3/12/2003, Ralf W. Grosse-Kunstleve wrote:
>
>  >The recent patch to lexical_cast.hpp causes problems under Mac OS X/gcc
>  >3.2.2.
>  >The error message appears at the top of:
>  >
>  >http://cci.lbl.gov/boost/results/1047512220/dailylog_coral_test
>  >
>  >.../boost/boost/lexical_cast.hpp:92: `wstring'
>  >   undeclared in namespace `std'
>  >
>  >This worked before:
>  >
>  >http://cci.lbl.gov/boost/results/1047490620/dailylog_coral_test
>  >
>  >(There are some other unrelated problems on this platform.)
>
> The same code also caused problems for Win32 GCC, Intel, and VC++ 6.0.
I've
> added a quick fix for lexical_cast.hpp line 92, which cleared a lot of the
> problems, but not all of them.
>
> See
> http://boost.sourceforge.net/regression-logs/cs-win32-RC_1_30_0-diff.html
> AFAIK, all the new fails are because of lexical_cast.hpp use.
>
> I've already privately emailed Kevlin and Terje, but given time zone
> differences they may not see the messages right away.
>
> This sort of last minute snafu reinforces Ralf's earlier message; it
really
> isn't good software development practice to sit on changes for months, and
> then try to get them working after a branch for release.

Not to mention getting a brand new version to work right away. The new
version of lexical_cast is Kevlin's own, which he recently made, not my
proposition. I think his version is better, though, as it's much shorter and
removes duplication. At the moment, it doesn't work well on MSVC 6, and
apparently has problems on other compilers, as well.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] MPL's "round" lambda

2003-03-10 Thread Terje Slettebø
A few months ago, Aleksey posted a cool way of doing lambda using function
notation. I hadn't followed the thread at the time, but I read up on it
recently. Like many others, I found it hard to understand how it worked, so
I asked Aleksey if he could make a minimal example of it, which he did.

For the benefit of anybody else interested in knowing how it works, I post
the example here. I found it much easier to understand how it works, with
such a minimal example.

--- Start ---

#include 
#include 
#include "boost/mpl/bind.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/static_assert.hpp"

using namespace boost::mpl;

template
struct expr
{
  typedef T type;
};

template
struct expr : bind2::type, typename
expr::type> {};

struct is_same : quote2 {};

// Here:

typedef apply, int>::type type;

BOOST_STATIC_ASSERT(type::value);

--- End ---


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Meta programming 'debug' mode.

2003-03-09 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >>From: "David Abrahams" <[EMAIL PROTECTED]>
> >
> >> I like the basic idea, but are you sure it will work in all the
> >> contexts where BOOST_STATIC_ASSERT works?  I think BOOST_STATIC_ASSERT
> >> functions like a declaration, syntactically.
> >
> > Then how about simply:
> >
> > #ifndef STATIC_NDEBUG
> > #define BOOST_STATIC_ASSERT2(e) BOOST_STATIC_ASSERT(e)
> > #else
> > #define BOOST_STATIC_ASSERT2(e) // Possibly "void(0)" here, like
> > "assert"
> > #endif
> >
> > By the way, what's the point with "void(0)", compared to nothing? Both
> > "void(0);" and ";" are valid statements.
>
> is ";" legal where a declaration is expected?
>
> class X
> {
>; // legal?
> };

Apparently not. "void(0)" doesn't work, either, so we need something else to
let it pass where declarations are allowed, as you say. It should be quite
easy. Of course, if BOOST_STATIC_ASSERT didn't require a ";" when used, one
could get away with defining it to nothing, as above, when STATIC_NDEBUG is
not set.

Defining it to BOOST_STATIC_ASSERT(true), as Jaap suggests in a recent
posting is also an option, if much of the processing is done in the
parameter passed, rather than in the macro itself (which is typically a
typedef or enum), which is likely.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Meta programming 'debug' mode.

2003-03-09 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Dirk Gerrits <[EMAIL PROTECTED]> writes:
>
> > Dirk Gerrits wrote:
> >  >
> >  > I'd say something like:
> >  >
> >  > #ifdef STATIC_NDEBUG
> >  > #define BOOST_STATIC_ASSERT2(e) BOOST_STATIC_ASSERT(e)
> >  > #else
> >  > #define BOOST_STATIC_ASSERT2(e) (void(e))
> >  > #endif
> >  >
> >  > Analogous to .
> >
> > Argh, the if and else branches should be reversed of course. You've
> > gotta love negative logic. ;)
>
> I like the basic idea, but are you sure it will work in all the
> contexts where BOOST_STATIC_ASSERT works?  I think BOOST_STATIC_ASSERT
> functions like a declaration, syntactically.

Then how about simply:

#ifndef STATIC_NDEBUG
#define BOOST_STATIC_ASSERT2(e) BOOST_STATIC_ASSERT(e)
#else
#define BOOST_STATIC_ASSERT2(e) // Possibly "void(0)" here, like
"assert"
#endif

By the way, what's the point with "void(0)", compared to nothing? Both
"void(0);" and ";" are valid statements.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-09 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>


> Terje Slettebø wrote:
> >
> > >From: "Jason House" <[EMAIL PROTECTED]>
> >
> > > Is there even a way to specify/change that?
> >
> > It isn't currently, as the fundamental types aren't handled as composite
> > types, and therefore aren't formatted using any set format. Also, it
seems
> > it may not be possible in an obvious way.
> > 
> > It appears to prefer the operator<<(char) stream member function, to
this
> > free function, as it isn't called when doing "std::cout << 'A';".
>
> :(
> It would be a good question to figure out why that won't work, and how
> to fix it...  What happens, in general, if somebody want to override a
> stream operator to do something else?

Well, outputting UDTs work fine, as you can then overload the operator<<.
However, as it's already overloaded, as a member function of the stream
class, for the built-in types, it doesn't help to overload it for them.

> String output probably uses
> character output by default... it would be very bad to have a system
> that made the string "string" (no quotes) output as 's''t''r''i''n''g'

Yeah. :) basic_istream/basic_ostream have overloaded stream operators for
CharType *, so they handle strings, in other words, the iostream versions of
gets()/puts().

> > > Debugger friendly manipulation would be good.  I still haven't thought
> > > about how exactly outputting of an arbitrary composite variable will
> > > work in the debugger by default...  I agree that having a wrapper
makes
> > > it easy for the output formatting of general types, but actually being
> > > able to execute "std::cout << my_suspect_variable" in the debugger
> > > without premeditation still poses a significant problem.  Why can't
bugs
> > > be predicted before you notice them?
> >
> > You're right, good point. Would it be possible to get some information
on
> > what kind of functions, if any, may be called in e.g. your debugger?
From
> > this, we may find what we can do.
>
> Well, I personally haven't gotten into the habit of calling functions
> for any debugger.

Me neither.

> I know that gdb allows that... and last that I tried
> it under the cygwin port, it wasn't very stable (but I kind of expect
> that in a cygwin port).  I do also remember hitting trouble trying to
> call templated types.  I believe that it could make calls to templated
> functions, but you needed to know the "real" name for the function...
> The base function name plus extra characters in order to distinguish
> it...  I might have gotten the "real" name off the call stack or
> something like that...
>
> Does that help to define "my debugger"?  I would hope to make it work
> for as many debuggers as possible (provided that they at least support
> making function calls)

Well, I guess that in either case, this may be handled through layering,
i.e. possibly providing convenience functions which calls the overloaded
stream operators, if the latter is difficult to call from a debugger.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-03-09 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > Right. There was a suggestion for allowing generic formats, though,
using
> > the same format for all instantiations of a template. The question is
how
> > to do it. The current version stores the format for each specific type,
as
> > you say. Volodya suggested a couple of ways it could be done, partial
> > specialisation, or storing the template name in a map. However, it could
be
> > hard to use the latter, as it could be hard to find the right type to
look
> > up, when outputting, given that you have specific types, not templates.
>
> Uhm... I meant that the right type should be explicitly written down:
>
> template
> ostream& operator<<(ostream&, const vector& v)
> {
> const composite_format& cf = composite_format::get("vector");
> }
>
> not nice, but should work.

Ah, I see. That would work.

> > If partial specialisation was used instead, you'd still need to specify
the
> > full type (even if only the generic format is set), and then, how to
> > differentiate between specific and generic format? For example:
> >
> > std::cout << io::set_format >(...); //
> > Uses partial specialisation of class template set_format for
std::vector,
> > setting generic format
>
> Oh... so here's the gotcha! I definitely don't like this syntax for
setting
> format for *all* vectors.

Me neither. It looks like it sets it for a specific type.

> Maybe, we can go even simpler way: introduce
> separate classes for all container kinds. BGL already has vecS, setS, and
so
> on. The syntax for setting format will be
>
>   cout << io::set_format(...) ;

Yeah, that could be a way.

> > > >From what I have thought about it, allowing a generic type creates
room
> > > for unexpected behavior in output when there are composite types
> > > containing composite types, and somewhere along the lines a *generic
> > > type* default is overridden.  There might be a specific reason for a
> > > bunch of lists inside of a composite type to have a specific set of
> > > delimiters...  but it probably isn't desired for the lists inside
those
> > > lists to be forced into using the same delimiters.
> >
> > Right. Well, as mentioned, the current version uses format for specific
> > types, so in that case, you could format each part of the nested
container
> > as you wanted, as shown with the 2D-array, which of course is an array
of
> > arrays.
>
> I think that nested containers should be handled in a more explicit way.
Why
> can't we allow to explicitly set braces/delimiters for container at
certain
> nesting level:
>
>   cout << io::set_format(...)
>
> would change delimiters only for top-level container. The question is that
the
> same code can be called both from top-level and when outputting some
> container. It would be possible to just reset nesting level, and restore
it
> after outputting.

Yeah, like with I/O state savers.

I'll do some more experimentation with this, and others are free to do the
same with the code, of course.

I haven't yet updated it much, from the version at Yahoo Files, since it
hasn't really been certain what the design should be.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Proposal: static_string library

2003-03-06 Thread Terje Slettebø
>From: "Robert Klarer" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > If run-time computation is ok, and that one only wants to avoid
dynamical
> > allocation, then one might do something like I used in another posting
in
> > this thread:
> >
> > template
> > class fixed_size_string;
> >
> > template
> > fixed_size_string operator+(const
> > fixed_size_string &s1, const fixed_size_string
> > &s2);
>
> An implementation of basic_string that uses the small string optimization
already
> implements something very close to this.  We don't need to specify an
entirely new
> kind of string to benefit from this technique.

True, for small strings. However, that particular technique doesn't work for
larger strings. I just mentioned the above, since it appeared that much of
the interest for static_string came from the lack of dynamical allocation,
so I wanted to point out that you don't need compile-time computation for
that.

Naturally, a compile-time string would be much less expensive to copy
around, though, since it's all encoded in the type, and there would be no
run-time cost for many operations.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Proposal: static_string library

2003-03-06 Thread Terje Slettebø
>From: "Beman Dawes" <[EMAIL PROTECTED]>

> At 05:58 PM 3/5/2003, Robert Klarer wrote:
>
>  >The purpose of the static_string library is to offer an alternative to
>  >string literals and the standard type const std::string.  A
>  >static_string uses no dynamically allocated memory, and is more
>  >efficient at execution time than either string literals or
>  >basic_strings.
>
> Yes, agreed. That would be useful. IIRC, the C++ committee's performance
> working groups has talked about such a string in the past.
>
> There are questions that come to mind:
>
> * Can you come up with a small, workable language extension that eases
> those problems?

Josuttis/Vandevoorde mentions being able to pass string literals as template
parameters as a possible future extension. That would be a clean way to
handle it. Possibly could there also be a general solution regarding passing
compound values. At the moment, values of class type can't be passed as
template parameters.

> * Can you come up with an alternate design that gives up a tiny bit of
> efficiency (one pointer indirection perhaps) but then allows reasonable
> construction and internationalization?

If run-time computation is ok, and that one only wants to avoid dynamical
allocation, then one might do something like I used in another posting in
this thread:

template
class fixed_size_string;

template
fixed_size_string operator+(const
fixed_size_string &s1, const fixed_size_string
&s2);

etc.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Proposal: static_string library

2003-03-06 Thread Terje Slettebø
>From: "Phil Nash" <[EMAIL PROTECTED]>

> > Robert Klarer wrote:
> > > The syntax for declaring a static_string is unfortunate, but once it
has
> > > been declared, a static_string's interface is (almost*) the same as
that
> > > of a const std::string.
> > Yes, you right it's unfortunate and IMHO is not appropriate for a wide
> use.
> >
> > >typedef boost::static_string<'s', 't', 'a', 't', 'i', 'c', '_'>
> > > StrType1;
> >
> I have to admit I like the idea of having a std::string interface without
> the overhead of dynamic allocation.

Well, you could get that using ordinary string types, as well, e.g.:

template
class fixed_size_string
{
  // ...

private:
CharType array[Size];
};

However, one thing the static_string may be used for, is for compile-time
computations, including passing it around as a template parameter, as shown
in the OP. The interface is rather inconvenient, though. I played some
around with this about half a year ago, too
(http://article.gmane.org/gmane.comp.lib.boost.devel/3032). However, I
didn't pursue it, because of the difficult way of specifying strings.

> My biggest reservation would by the char-only restriction...

You could also use wchar_t, of course, or any fundamental type, if that's
what you mean?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] coding style

2003-03-06 Thread Terje Slettebø
>From: "Joel Young" <[EMAIL PROTECTED]>

> I find other people's code with long linelengths is cause by either too
> much nesting or by putting too many concepts on one line...

That doesn't have to be the case. There can easily be lines longer than 80
characters, which only contain one statement or expression, i.e. one
concept, regardless of nesting.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: resource manager naming

2003-02-28 Thread Terje Slettebø
>From: "Joel de Guzman" <[EMAIL PROTECTED]>

> > manager
> >
> > Manager of widget. It's kind of implied that what is managed is the
> > resource itself, even though "resource" doesn't say anywhere. This is
> > similar to that you think it's implied that resource means it
> > manages the resource, even though "manage" doesn't say anywhere.
>
> Look at it this way. Which noun best describes the following:
> 1) You acquire it
> 2) You release it
> 3) You transfer its ownership
>
> A) manager
> B) resource
> C) managed

Resource.

> > "resource_manager" starts to look attractive, again. ;)
>
> Perhaps. But there's a *better* and *shorter* alternative that very well
fits
> the description. We can say: linear_list_of_items_manager, YUCK!
> Instead, we say list. The management *is* implicit!

Right.

> Also, in general, I would say that any name suffixed by "_manager" are
best
> used for classes that manage *many* things simultaneously, NOT JUST ONE.
> Take a window_manager for example. It is something that manages the
operations
> of many windows. In the Macintosh, for example, the resource manager
manages
> "all* the resources in an application.

Right again.

Ok, I agree that resource<> may be a useful name for it, with implied
management, like e.g. std::list<>, as you say.

Anyway, as Dave A points out in another posting, and which was also the
topic of an earlier of mine, the usefulness of the concept in the first
place hasn't been demonstrated.

The reason I jumped in on the naming discussion, is that I thought
managed<>, or rather manager<> could be a possibility, as well. I thought
the same that Dave said, that resource doesn't really tell me much,
as it seems it's saying the same thing twice; widged is a resource.

Also, as Gennadiy points out, list<> is a list, while resource<> is not a
resource; it's a manager of a resource.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: resource manager naming

2003-02-28 Thread Terje Slettebø
>From: "Joel de Guzman" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >> From: "Joel de Guzman" <[EMAIL PROTECTED]>
> >
> >> Dave Gomboc wrote:
> >>>>> So then reverse resource_manager and get managed_resource<>, or
> >>>>> just managed<>.
> >>>>
> >>>> Why not just resource<>? Management is implied anyway; that's the
> >>>> reason for the existence of the class.
> >>>
> >>> *laugh*  I was thinking exactly the opposite.  To me, the resource
> >>> itself
> >>> is clear from the template parameter -- it's the management that
> >>> needs to
> >>> be indicated.
> >>>
> >>> +1 for managed<>.
> >>
> >> What template parameter? That's not a part of the name.
> >> Template parameters, just like function arguments are never
> >> a part of the name. You do not need to read the header file
> >> to get the essence. The name itself should indicate the function
> >> of the class without looking elsewhere.
> >>
> >> managed<>? What is managed? ... answer: take a look at
> >> the template parameter and you'll see what I mean. I'm
> >> sorry, that doesn't make sense.
> >
> > managed
> > managed // Smart pointer
> >
> > resource
> > resource // Smart pointer
> >
> > When the template is in use (unless it uses a default template
> > argument),
> > the template argument will be part of the signature, and therefore
> > show what is managed. Therefore, I think managed<> makes sense, too.
> >
> > IIUC, your argument can be used for e.g. std::pair, too. std::pair<>
> > of
> > what? Answer: That depends on the template arguments.
>
> No, a pair is always a pair regardless of what the composed types are:
>
> pair // a pair comprised of T1 and T2
>
> You don't need to know the template parameters to know that it
> is a *pair*. That's the big difference. The template parameter is an
abstract
> concept. Detached from the parameters, it is still a pair. The same does
not
> hold for managed. What is "managed"? It is not even a noun without the
> qualifiers.

Good point, it's not a noun. "resource_manager", "manager" or "resource" are
nouns, so they may be better.

> managed // does this *manage* the actual rendering into the
window?
>
> Gotcha! No it doesn't!

To adjust it so it becomes a noun:

manager

Manager of widget. It's kind of implied that what is managed is the resource
itself, even though "resource" doesn't say anywhere. This is similar to that
you think it's implied that resource means it manages the resource,
even though "manage" doesn't say anywhere.

By the way, I used "widget" in the meaning of "anything", as it's used some
places (like "foo" and "bar").

"resource_manager" starts to look attractive, again. ;)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: resource manager naming

2003-02-27 Thread Terje Slettebø
>From: "Joel de Guzman" <[EMAIL PROTECTED]>

> Dave Gomboc wrote:
> >>> So then reverse resource_manager and get managed_resource<>, or just
> >>> managed<>.
> >>
> >> Why not just resource<>? Management is implied anyway; that's the
> >> reason for the existence of the class.
> >
> > *laugh*  I was thinking exactly the opposite.  To me, the resource
> > itself
> > is clear from the template parameter -- it's the management that
> > needs to
> > be indicated.
> >
> > +1 for managed<>.
>
> What template parameter? That's not a part of the name.
> Template parameters, just like function arguments are never
> a part of the name. You do not need to read the header file
> to get the essence. The name itself should indicate the function
> of the class without looking elsewhere.
>
> managed<>? What is managed? ... answer: take a look at
> the template parameter and you'll see what I mean. I'm
> sorry, that doesn't make sense.

managed
managed // Smart pointer

resource
resource // Smart pointer

When the template is in use (unless it uses a default template argument),
the template argument will be part of the signature, and therefore show what
is managed. Therefore, I think managed<> makes sense, too.

IIUC, your argument can be used for e.g. std::pair, too. std::pair<> of
what? Answer: That depends on the template arguments.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: smart_ptr vs smart_resource

2003-02-26 Thread Terje Slettebø
>From: "Phil Nash" <[EMAIL PROTECTED]>

> [Terje Slettebø]
> > I also think this makes sense. However, I'm wondering how much
commonality
> > there is in such a broader concept. This is kind of making a library
> > implementation of the RAII idiom, and we have that already, in the form
of
> > constructors/destructors.
>
> Yes.. it's ctors and dtors that have really brought the RAII idiom into
the
> language - and of course is very important in the resource_manager
concept.
> Now, to your example:
>
> > Looking at my own code, to find such use, I've found a few places, such
as
> > the following:
> >
> > // Direct3D
> >
> > class vertex_buffer_lock
> > {
> > public:
> >   vertex_buffer_lock(vertex_buffer_base &vb,vertex *&vertices,const uint
> > num_vertices,const uint flags =0) :
> > vertex_buffer(vb)
> >   {
> > vertex_buffer.lock(vertices,num_vertices,flags);
> >   }
> >
> >  ~vertex_buffer_lock()
> >   {
> > vertex_buffer.unlock();
> >   }
> >
> > private:
> >   vertex_buffer_base &vertex_buffer;
> > };
> >
> > Would a resource_manager provide anything additional, here? I'd still
need
> > to write a policy which would be really the same as the above. Also, how
> > would a resource_manager handle all the different constructors?
>
> Well, as you so rightly point out, full RAII wrappers for such resources
> would require you to write most, if not all, of the code yourself -
although
> I wonder if a resource_manager framework would still make getting them
right
> easier... (I'd need to give that more thought). One advantage would be
that
> the release mechanism would be independant of any other aspects of the
> wrapper - and so could be ensured to be more robust in the face of
> exceptions without you having to worry about it directly.

I'm not sure what you mean, here. In the above example, the destructor takes
care of the release. Also, as it only manages _one_ resource (the lock), it
is exception safe (vertex_buffer (which inherits from vertex_buffer_base) is
just a wrapper class for D3D's VertexBuffer interface). Speaking of that, I
also have a COM smart pointer class there. That could definitely make use of
a smart pointer/resource manager, as it could then make use of the pointer
semantics, etc.

Even as a policy, you'd still have to make sure that your acquire/release
functions are exception safe, just like the constructor/destructor above. So
I don't see how a resource_manager class would add anything in this respect.

> On a related note
> the various copying policies would be taken care of for you. If you want
to
> make your resource copyable, or shareable or COWable or whatever - it just
> takes a change of policy to give you the feature (if appropriate).

Which reminds me, the class above actually was defined as:

class vertex_buffer_lock : private boost::noncopyable

Yes, if you could make the copying/ownership policy independent of what is
owned, for example by making it call acquire/release functions on another
policy, which implements the code in the constructor/destructor above.

> > Also, if you use "T &" for the
> > constructor arguments, you risk getting reference to reference problems.
>
> I believe this can be fixed with type_traits.

Come to think of it, it may not be a problem, after all. Consider this
simple test program:

class test
{
public:
  test(int &) {}
};

template
class resource_manager
{
public:
  resource_manager() : resource() {}

  template
  resource_manager(T1 &t1) : resource(t1) {}

private:
  T resource;
};

int main()
{
int i=1;

resource_manager testA(i);

int &ir=i;

resource_manager testB(ir);
}

This compiles and runs without any problems.

> > In short, I think it could be good to find a few use-cases, such as the
> > above, and try to implement it using a generic resource_manager. That
> would
> > show if the concept adds anything, or not. In other words, let the
rubber
> > meet the road. :)
>
> Yes.. some examples have already been given, including managing file
handles
> (although in practice we already have an RAII file object in the form of
> fstream), mutex locks (which saw the resurrection of this thread
recently),
> and all sorts of OS handles and other resources that are usually presented
> as a C interface.

Yes, I know there's a lot of use cases. My emphasis was on _implementing_
them. :) That way, one get to see if they may be handled uniformly by such a
framework.

> Several times now I have had to write my own wrappers for the MS Inet HTTP
> interface, purely to provide the RAII mana

Re: [boost] Re: smart_ptr vs smart_resource

2003-02-26 Thread Terje Slettebø
>From: "Phil Nash" <[EMAIL PROTECTED]>

> [Rob Stewart]
> > There can still be a smart_ptr class, even if there's a
> > smart_resource class.  Both may be separate manifestations,
> > possibly sharing some implementation details, of a SmartResource
> > concept.  Equally plausible, smart_ptr could be implemented in
> > terms of smart_resource somehow (derivation, aggregation,
> > whatever).
>
> In the Policy Based case smart_ptr would just be smart_resource (or
> resource_manager) with certain policies (or policy sets). Template
typedefs
> would help a lot here.

I also think this makes sense. However, I'm wondering how much commonality
there is in such a broader concept. This is kind of making a library
implementation of the RAII idiom, and we have that already, in the form of
constructors/destructors.

Looking at my own code, to find such use, I've found a few places, such as
the following:

// Direct3D

class vertex_buffer_lock
{
public:
  vertex_buffer_lock(vertex_buffer_base &vb,vertex *&vertices,const uint
num_vertices,const uint flags =0) :
vertex_buffer(vb)
  {
vertex_buffer.lock(vertices,num_vertices,flags);
  }

 ~vertex_buffer_lock()
  {
vertex_buffer.unlock();
  }

private:
  vertex_buffer_base &vertex_buffer;
};

Would a resource_manager provide anything additional, here? I'd still need
to write a policy which would be really the same as the above. Also, how
would a resource_manager handle all the different constructors? Perhaps
using overloaded, templated constructors. That wouldn't cater for default
arguments, like the above, though. Also, if you use "T &" for the
constructor arguments, you risk getting reference to reference problems.

In short, I think it could be good to find a few use-cases, such as the
above, and try to implement it using a generic resource_manager. That would
show if the concept adds anything, or not. In other words, let the rubber
meet the road. :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: io operations for stl containers?

2003-02-25 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>
> >
> > std::vector > test;
> >
> > std::cout << test: // Using defaults
> >
> > (('A',1),('B',2),('C',3))
>
> I would suspect that chars don't get output with '' around them...

Right. I was just thinking C++ code, here. :)

> Is there even a way to specify/change that?

It isn't currently, as the fundamental types aren't handled as composite
types, and therefore aren't formatted using any set format. Also, it seems
it may not be possible in an obvious way. For example, the following
addition to the header doesn't work:

template
std::basic_ostream &operator<<
  (std::basic_ostream &stream,char value)
{
  typedef basic_composite_format format_type;

  const format_type &format=format_type::format(stream);

  stream << format.start;
  stream.operator<<(value);
  stream << format.end;

  return stream;
}

It appears to prefer the operator<<(char) stream member function, to this
free function, as it isn't called when doing "std::cout << 'A';".

> > In this case, it's not possible to set the format for each type
separately.
> > Maybe it could be good to keep that feature of the current composite
> > operators, as well, something like:
> >
> > typedef std::pair map;
> > typedef std::vector map_list;
> >
> > map_list test;
> >
> > std::cout << io::set_delimiter("\n") << test;
> >
> > Output:
> >
> > (('A',1)
> > ('B',2)
> > (C,3))
>
> so basically, you would like to combine tuple-like output specification
> (ie for all tuples) and type specific such as composite_format?

I was thinking of that, yes. As well as a default, possibly user-settable,
for any type not having set an explicit format. This would let you control
the formatting in layers, so to speak:

- You could use/set the default format for all types.
- You could use/set the format for all instantiations of a given template,
e.g. std::vector.
- You could use/set the format for specific types.

If possible, it would apply the most specific format set (i.e. it would
prefer 3 to 2, to 1).

Another thing is if this layering is practically possible. :) We get into
this below here.

> > template
> > inline std::basic_ostream&
> > operator<<(std::basic_ostream& o,
> >const cons& t)
> >
> > As you say, this may be a problem to call from a debugger, unless it
> > supports calling function templates. If one need to call it from a
debugger,
> > one could always wrap the code in a function.
>
> :(
> Debugger friendly manipulation would be good.  I still haven't thought
> about how exactly outputting of an arbitrary composite variable will
> work in the debugger by default...  I agree that having a wrapper makes
> it easy for the output formatting of general types, but actually being
> able to execute "std::cout << my_suspect_variable" in the debugger
> without premeditation still poses a significant problem.  Why can't bugs
> be predicted before you notice them?

You're right, good point. Would it be possible to get some information on
what kind of functions, if any, may be called in e.g. your debugger? From
this, we may find what we can do.

> > There was a suggestion for allowing generic formats, though, using
> > the same format for all instantiations of a template. The question is
how to
> > do it. The current version stores the format for each specific type, as
you
> > say. Volodya suggested a couple of ways it could be done, partial
> > specialisation, or storing the template name in a map. However, it could
be
> > hard to use the latter, as it could be hard to find the right type to
look
> > up, when outputting, given that you have specific types, not templates.
> >
> > Overloading of class templates might have helped, here. E.g.:
> >
> > std::cout << io::set_format >(...); //
Set
> > specific format (io::format is a class template)
> > std::cout << io::set_format(...); // Set generic format for
> > std::vector (io::format overloaded with a version taking template
template
> > parameter, and specialised for std::vector)
>
> Well,  would cause trouble because the std::vector requires
> extra arguments...  I don't think you could get that to compile.

True, it doesn't, because it's not currently legal C++. :) That's what I
meant with "Overloading of class templates might have helped, here." It's
not possible to overload class templates. However, this is mentioned as a
possible extension, in the "Future Directions" chapter of
Josuttis/Vandevoorde. Together with partial specialisation of function
templates, etc.

> Using
> a string might work... but using it as a template argument would
> probably cause trouble.

Yes, you can't use string literals as template parameters.

> I don't know if there is a way to use partial
> template specialization.

There is, as I showed in the following example. However, it means you have
to provide the parameters to the template, as well (e.g. std::vector), even
if you just mean to set the format for any instantiation of the template.

> There was a recent post about convertin

Re: [boost] Re: io operations for stl containers?

2003-02-24 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >
> > >From: "Vladimir Prus" <[EMAIL PROTECTED]>
> >
> > Sorry for having taken so long to respond to these messages. I felt a
need
> > for a break, to consider how it might be done.
>
> I was wondering about this line of discussion earlier today... wondering
> if it died on the vine or not.  I'm glad to see that it hasn't

Right. After I had sent it, I found that "break" wasn't quite right. I meant
that I had been considering it, including what had been said in the thread.

Specifically, like I said in an earlier posting, I was wondering if there
was enough commonality to warrant a library implementation. Then I happened
to look more into Boost.Tuple, and realised that even a simple solution
could be useful, as you and others have pointed out, as well.

> > In a way, something good came from it, as well: I've recently looked at
> > Boost.Tuple, and I see that they have I/O operators defined (in
> > tuple_io.hpp).
>
> Well, it definitely seems like the tuples were thinking along similar
> lines with a start, middle, and stop delimiters.
> The documentation brings up a point about parseability of data streams.
> It doesn't quite make sense to me that there should be restriction to a
> single character in order to to make things uniquely parseable.  If it's
> a fixed sequence of characters, I don't see how that makes it any
> significantly less parseable...  Maybe I'm missing something?

The docs says:

"Note that extracting tuples with std::string or C-style string elements
does not generally work, since the streamed tuple representation may not be
unambiguously parseable."

It's not about the delimiters. which it seems you mean, but about the tuple
elements. Consider:

tuple test;

stream >> test; // Stream contains "a string, with comma, 123"

Here, it can't know that the first comma is part of the string, and not
meant to separate elements. Not to mention that it would stop after "a", due
to the space character.

I agree that it should be possible to have multi-character delimiters,
without creating parsing problems. It could be an idea to keep this, as it
may make for more flexible output. Even single-character delimiters is quite
flexible, as you can even get each element on its own line, by using '\n' as
the element separator. To look again at one example of how the tuple way
might work:

std::vector > test;

std::cout << test: // Using defaults

(('A',1),('B',2),('C',3))

In this case, it's not possible to set the format for each type separately.
Maybe it could be good to keep that feature of the current composite
operators, as well, something like:

typedef std::pair map;
typedef std::vector map_list;

map_list test;

std::cout << io::set_delimiter("\n") << test;

Output:

(('A',1)
('B',2)
(C,3))

Or, generating program-code like listing:

std::cout << io::set_format("{\n","}\n",",\n")
  << io::set_format("{","}",", "}
  << test;

{
{'A', 1},
{'B', 2},
{'C', 3}
}

Maybe also:

std::cout << io::set_format("(\n",")\n","\n") << io::set_indent(2)
<< test;

(
  ('A',1)
  ('B',2)
  ('C',3)
)

You might also have a non-template overload of the manipulators, which sets
the delimiters for all types, as done in tuples.

This may also have a positive effect on a serialisation library: The
standard types will have default stream operators.

> It does enable defaults and allows a way to customize each spacer
> individually, which is a good addition.  I think the ability to set all
> 3 also is a must-have :)

Yeah, I think that's useful, too. :)

> The tuple functions, as provided should be extremely easy to call from a
> debugger since there is no templating going on.

Actually, there is. They are defined in tuple_io.hpp as:

template
inline std::basic_ostream&
operator<<(std::basic_ostream& o,
   const cons& t)

As you say, this may be a problem to call from a debugger, unless it
supports calling function templates. If one need to call it from a debugger,
one could always wrap the code in a function.

> I think that if when
> composite_format matures, there should be a way to add non-templated
> calls to change defaults.
> maybe:
> namespace composite_format{
>   namespace tuple{
> ... set_open(char x){ return composite_format_open(x); }
>   }
> }

The manipulators might also be handled the same way as above, wrapping them
in the function.

> Actually that

Re: [boost] Re: io operations for stl containers?

2003-02-24 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

Sorry for having taken so long to respond to these messages. I felt a need
for a break, to consider how it might be done.

In a way, something good came from it, as well: I've recently looked at
Boost.Tuple, and I see that they have I/O operators defined (in
tuple_io.hpp). To quote from the docs:

--- Start quote ---

Streaming

The global operator<< has been overloaded for std::ostream such that tuples
are output by recursively calling operator<< for each element.

Analogously, the global operator>> has been overloaded to extract tuples
from std::istream by recursively calling operator>> for each element.

The default delimiter between the elements is space, and the tuple is
enclosed in parenthesis. For Example:

tuple a(1.0f,  2, std::string("Howdy folks!");

cout << a;

outputs the tuple as: (1.0 2 Howdy folks!)

The library defines three manipulators for changing the default behavior:

- set_open(char) defines the character that is output before the first
element.
- set_close(char) defines the character that is output after the last
element.
- set_delimiter(char) defines the delimiter character between elements.

Note, that these manipulators are defined in the tuples subnamespace. For
example:

cout << tuples::set_open('[') << tuples::set_close(']') <<
tuples::set_delimiter(',') << a;

outputs the same tuple a as: [1.0,2,Howdy folks!]

The same manipulators work with operator>> and istream as well. Suppose the
cin stream contains the following data:

(1 2 3) [4:5]

The code:

tuple i;
tuple j;

cin >> i;
cin >> tuples::set_open('[') >> tuples::set_close(']') >>
tules::set_delimiter(':');
cin >> j;

reads the data into the tuples i and j.

Note that extracting tuples with std::string or C-style string elements does
not generally work, since the streamed tuple representation may not be
unambiguously parseable.

--- End quote ---

Maybe these routines could be generalised, and used for any
composite/compound type, including tuples?

If it's good enough for the standard library (given that Boost.Tuple have
been accepted in the Library TR), it may be good enough for the other types,
as well. :)

> Terje Slettebø wrote:
> >>From: "Jason House" <[EMAIL PROTECTED]>
> >
> >
> >>Terje Slettebø wrote:
> >>
> >>
> >>>Regarding this project. I've got doubts about the viability of it.
> >>
> >>Well, I'm glad you've given it a greater level of thought.  I really
like
> >
> > the idea
> >
> >>of the composite_format, and probably should try to do the same :)
> >
> >
> > Thanks for your feedback. I like the idea, as well. We have I/O for
single
> > objects, but no specific way for composites. The question is if we
should
> > have that. :) Maybe the reason we don't have it, yet, is that it may be
hard
> > to come up with a system that is general enough, yet easy to use.
>
> Most likely I don't need to say it again, but having fixed i/o operators
with
> fixed output format is better that have nothing. As you've noticed, my
> original motivation was debugging output, and I still find this important
enough.

You're right.

That was probably the motivation for Boost.Tuple's stream operators, as
well: A minimal, easy to use interface, with sensible defaults.

> >>>One thing is to create something useful. Another thing is to create
> >>>something useful as a _library_ component. As has been noted regarding
> >>>application and library development, application development and
library
> >>>development is typically quite different. With an application, you
> >
> > typically have quite specific requirements. With a library component,
however,
> > it's about anticipating future use. Or making something general enough
to be
> >>>useful as a library component.
>
> But you don't write library, put a seal on it, and stop. There's nothing
wrong
> with making it more flexible when users demand it. As it stands, only few
> persons are interested in the simplest facilities. Is it worth spending
time
> on completely generic/flexible solution if no-one has expressed desire for
it?

Right, again. What do you think of the Boost.Tuple approach?

In your original posting, you said:

>I was thinking about
>
>   
>   
>
>and so on. There are basically two approaches:
>
>1. Operators use fixed format: bracked list with commas between values for
>vector, for example.
>2. Manipulators are provided to set brackets and separators.
>
>I had implemented the second 

Re: [boost] Re: io operations for stl containers?

2003-02-07 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > Regarding this project. I've got doubts about the viability of it.
>
> Well, I'm glad you've given it a greater level of thought.  I really like
the idea
> of the composite_format, and probably should try to do the same :)

Thanks for your feedback. I like the idea, as well. We have I/O for single
objects, but no specific way for composites. The question is if we should
have that. :) Maybe the reason we don't have it, yet, is that it may be hard
to come up with a system that is general enough, yet easy to use.

Since I posted this, I've been reading the discussion on
serialisation/persistence, such as Jens Maurer's, and Robert Ramey's
recently reviewed serialisation library. It seems there were similar issues
there: It was hard to find one way of doing it, which could be generally
agreed on.

It may actually be easier to come up with a system for serialisation, at
least when it comes to the serialised format, since the format to use for
serialisation may be easier to define. However, for operators for
human-readable I/O, there's a potentionally large variation in how you might
want to do it.

In the case of the composite operators, nobody has complained about lack of
generality, or ease of use, but I've been thinking about this issue, myself.

The point with my posting was also to solicit feedback from others on the
issue, what they think about it, what it could be used for. It would help
define the application domain (also called problem domain).

> > One thing is to create something useful. Another thing is to create
> > something useful as a _library_ component. As has been noted regarding
> > application and library development, application development and library
> > development is typically quite different. With an application, you
typically
> > have quite specific requirements. With a library component, however,
it's
> > about anticipating future use. Or making something general enough to be
> > useful as a library component.
>
> Very true,  but some libraries are useful simply because they're simply
code that
> people would write themselves over and over... only done in a better way.

Yeah. Also, Björn Karlsson had an informal questionnaire on the list a while
ago, about what people were using Boost for, and it turned out to be
especially the simple components (not necessarily simple in implementation,
by all means, but simple in concept) which were used, such as ref, bind,
function objects, the smart pointers, etc.

These are components which, as I mentioned, does one thing, and one thing
well. That makes it easier to use/reuse these components in different
contexts, as they are like building blocks.

Of course "one thing" may be anything. In the case of MPL, it's a framework
for metaprogramming, where each component does one thing. Thus, it provides
a "language" for making things.

> In the
> current state of discussion, it sounds like something that I would
definitely
> use.  I've implemented poor versions on the fly in the past... always more
> specific than composite_format...  One big use of special display
> functions/operators is that you can call them from the debugger.  If there
was a
> debug-time friendly version of composite object output functions... and
all I
> needed to do was #include a specific header, that would be absolutely
fantastic!

Aha. Good point.

> > You may do this:
> >
> > for(MapList::const_iterator i=list.begin(); i!=list.end(); ++i)
> >   std::cout << '[' << i->first << ',' << i->second << "]\n";
> >
> > Or you may do:
> >
> > std::cout << composite_format("[", "]", "\n") << list;
> >
> > The question is, is it worth it?
> >
> > Of course, having defaults, the latter may be reduced to:
> >
> > std::cout << list;
>
> I absolutely hate not being able to do this last one by default.  Having a
well
> written default for this makes it all worth it for me!  The for loop has
no chance
> of being evaluated properly in a debugger, but a debugger can likely call
the <<
> operator with less difficulty.

Right.

> How easilly can a debugger print out an STL object?  I know that gdb can
call
> functions that are defined in the code.  For templated functions, this is
probably
> a major hassle.  Could there be some way to enable a debugger to call a
function
> like this?  If so, what's the best way to enable that without massive
efforts from
> the user?

I guess it depends on the debugger. I've typically done such printing
explicitly in the code, rather than invoking it in the 

Re: [boost] Re: io operations for stl containers?

2003-02-07 Thread Terje Slettebø
Regarding this project. I've got doubts about the viability of it.

One thing is to create something useful. Another thing is to create
something useful as a _library_ component. As has been noted regarding
application and library development, application development and library
development is typically quite different. With an application, you typically
have quite specific requirements. With a library component, however, it's
about anticipating future use. Or making something general enough to be
useful as a library component.

I've thought a lot about this, these days, regarding the composite
operators. Trying to find the essential abstraction. Clearly, they are about
passing composite objects (such as arrays, standard containers, etc.) to a
stream, so that is the abstraction. This is also something which isn't
covered much in current libraries. The question is if there's enough
commonality in this abstraction, to warrant a library implementation.

For the composite operators to be genuinely useful in a broader context, I
think it's important that they do one thing, and one thing well.

The challenge is to make something general enough, yet reasonably easy to
use. Easy things should be easy, and hard things should be possible.

My concern is, for example, for outputting a
std::vector >:

typedef std::pair Map;
typedef std::vector MapList;

MapList list;

You may do this:

for(MapList::const_iterator i=list.begin(); i!=list.end(); ++i)
  std::cout << '[' << i->first << ',' << i->second << "]\n";

Or you may do:

std::cout << composite_format("[", "]", "\n") << list;

The question is, is it worth it?

Of course, having defaults, the latter may be reduced to:

std::cout << list;

It also comes back to the question of commonality and variability.
Currently, it uses static strings for start, end, and element delimiter.
Anything else, and you need to use something else.

I was first thinking of generalising it to any string type (rather than
std::basic_string), but I've found that even that doesn't go far enough, if
you want to change it radically. I've then been thinking of the possibility
of passing a functor, instead, to the manipulator. The manipulator could
then invoke this functor for each element to be output. This would enable
things like listing element number in the output, by passing in an
appropriate functor for this. The current semantics might be catered for by
another functor, and overloaded constructors for this case may also be
provided for convenience.

BGL is similar, in that graphs are also composite objects. It uses
"visitors", which are functors with multiple member functions (not just
overloaded operator()), which are called at specific points in an algorithm.
The same could be done with the composite operators, calling the functor at
start, end and for each element.

However, as the algorithm in this case is just iterating over a sequence,
calling a functor or outputting each element, it's more or less the same as
a for-loop, or for_each.

It's also a question of what design space we are targeting: Originally,
Vladimir Prus's suggestion was for something that could help with debug
output. It's a question whether or not this can be made general enough to be
useful beyond that, and if that is even desirable, concerning things like
usability.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-07 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Jason House wrote:
>
> > Terje Slettebø wrote:
> >
> > > Another possibility might be to have a sentry object, doing automatic
state
> > > saving and restoring in the constructor and destructor. In fact, there
are
> > > already such classes in Boost: Daryle Walker's I/O state savers, which
fits
> > > this situation like a glove.
> >
> > I think that I like your solution better :)  putting it
constructor/deconstructor
> > does seem better.  I can't even argue that it's more typing for
multi-line
> > expressions...
>
> Well, I know at least have more fuel to think about...
> First of all, does your constructor take the stream as an argument?  It
would have to
> in order to do state saving in the constructor...  If so, that at least
makes prevents
> the following case (that probably needs special handling)
> {
>   io_format<> var1(...);
>   std::cout << var1 << stuff;
>   std::cerr  << var1 << more_stuff;
> }
>
> My understanding is that the constructor would not perform state saving,
but that it
> is the call to << that has to perform the locking.

Right. In the example I had, << performed the saving. In that case, it would
have to check a save-flag in the destructor. One could also pass the stream
to it in the constructor, as you say.

> So what happens when multiple streams are used?

That's no problem. The format is set for a specific stream (each stream has
its own iword/pword for the type to be output). So for the free-standing
saver, it would need to take the stream as a constructor argument.

> what happens when you have 2 or more io_formats in the same function used
on the same
> stream?
> example
> {
>   io_format var1(...), var2(...);
>   std:: cout << var1 << stuff1;
>   std::cout << var2 << stuff2;
>   std::cout << var1 << stuff3;
>   std::cout << var2 << stuff4;
>   std::cout << io_format(...) << stuff5;
> }  /* deconstruct all 3 io_format's ... not necessarilly in the right
order! */

This should work just fine. When the manipulator is used, it sets the format
given by it. When a new manipulator is used, it changes the format to the
new one. Also, the language ensures that the objects are destroyed in the
reverse order of creation, so they will all be deleted after the last
statement above.

> Here, var1, var2, and the unnamed class from the last line in the function
are all
> being deconstructed at the same time.  Some caution needs to occur here.

Well, as this version of them just sets the format, and doesn't do anything
in the destructor, their order of destruction doesn't matter for the output.

> Is that what the state-saver class you referred to does already?

That one does the restoring in the destructor. If we used the combined
setter/saver/restorer I mentioned in the posting I just sent, them only the
first of the above formats (var1), needed to save the format, to ensure that
the format wasn't changed by the output statements.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-07 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > >From: "Jason House" <[EMAIL PROTECTED]>
> > > I thought of one thing that might work reasonably well.
> > >
> > > How about making ++io_format< T > save the current format in a stack.
> > > and having io_format< T>-- restore the previously queuued format
> >
> > > so, then something like
> > >
> > > > > std::cout << ++io_format("\n|","|\n","|")--
> > > > >   << ++io_format > (&)[3][3]>("---","---","---")--
> > > > >   << board << '\n';
> > >
> > > would save and restore the formating for char(&)[3][3] and char(&)[3]
and
> > never stomp on anything else.
> >
> > In this case, it seems it saves and restores the format, before the
format
> > gets a chance to be used. In other words, the scope only covers the
state
> > saving, not the output.
>
> The idea was pre-increment and post-decrement...  I wasn't sure if pre &
post
> operators work the same for classes as they do for primitive types.

Well, you can define them like that, as well. However, even in that case,
because of operator precedence, it will evaluate ++ and --, before <<, so it
would save and restore the state, before outputting.

> > std::cout << composite_save >() << composite_format(...) <<
v <<
> > '\n';
> >
> > An alternative is a named temporary, such as:
> >
> > composite_save > sentry(stream);
> >
> > // Set format and do output
>
> I think that I like your solution better :)  putting it
constructor/deconstructor
> does seem better.  I can't even argue that it's more typing for multi-line
> expressions...

Come to think of it, we may get the best of both worlds. :) Since the format
manipulator object also is a temporary, it can do the saving/restoring. :)

You could then do e.g:

std::cout << composite_format(...,true) << v;

This saves the format, changes it, performs output, and restores the format
in the destructor.

Likewise:

composite_format sentry(std::cout,...,true); // Save format, and set new
format. Restore in destructor.

// Do output

std::cout << composite_format(...) << v; // Doesn't save/restore the format

Alternatively, it could default to save.

> When I originally started this, I said that it was the same complaint I
have about
> io_manip...  It would be neat to have a replacement/wrapper boot library
for
> io_manip.

I think the mentioned Boost I/O state savers would do that job well. That's
exactly what they are for. Have you looked at them?


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-05 Thread Terje Slettebø
>From: "Larry Evans" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >>From: "Vladimir Prus" <[EMAIL PROTECTED]>
> >
> >>Terje Slettebø wrote:
>
> [snip]
> >
> > std::cout << io_format("\n|","|\n","|")
> >   << io_format("---","---","---")
> >   << board << '\n';
> > }
> >
> > we get:
> >
> > ---
> > |O|X|O|
> > ---
> > |X|X|O|
> > ---
> > |O|O|X|
> > ---
>
> I've used marg_ostream to format output for containers; however,
> it only used something that changed the margin.  I had to
> use an ostream<< for the particular composite to get it to work.
> However, being able to adjust the margin seems useful for
> formating most code.  Looking at the code might give you
> some more ideas about your io_format.  Unfortunately, marg_ostream
> requires wrapping the cout in a marg_ostream.
>
> Anyhow, the code is in boost files in
shared_cyclic_ptr/shared_cyclic_ptr.zip
> in boost/col_io directory.  Basically, marg_ostream++ increments the
> margin and marg_ostream-- decrements the margin.  You can also specify
> what's in the margin.  This was used to show the nesting in a fortran
> program in a parallelizing compiler.

Thanks for the tip. I'll look into it.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-05 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > > It should handle maps and pairs
> > > reasonably well.  I think that I have the same complaints about this
as
> > > io_manip
> > >
> > > The saving of information to the stream means that you can affect all
> > > future output...
> > >
> > > For instance, if you have a type
> > > map >
> > >
> > > and custom_object's stream output uses io_format >, then
> > > you are going to run into trouble if it wants a different formatting.
> >
> > Right. That's a consequence of this. As you say too, I don't know any
> > obvious alternatives, though.
>
> I thought of one thing that might work reasonably well.
>
> How about making ++io_format< T > save the current format in a stack.
> and having io_format< T>-- restore the previously queuued format

I've thought of the exact same thing. :) Not how the syntax for it would be,
but when I was thinking of this, it suddenly occurred to me: State savers!

This essentially creates a scope in the state space. As you say, you may
then read the currently set format, and restore it afterwards. The
restoration is important, and there are issues such as exception safety.

> so, then something like
>
> > > std::cout << ++io_format("\n|","|\n","|")--
> > >   << ++io_format("---","---","---")--
> > >   << board << '\n';
>
> would save and restore the formating for char(&)[3][3] and char(&)[3] and
never
> stomp on anything else.

In this case, it seems it saves and restores the format, before the format
gets a chance to be used. In other words, the scope only covers the state
saving, not the output.

Another possibility might be to have a sentry object, doing automatic state
saving and restoring in the constructor and destructor. In fact, there are
already such classes in Boost: Daryle Walker's I/O state savers, which fits
this situation like a glove.

In your original posting, you had this example:

>For instance, if you have a type
>map >

>and custom_object's stream output uses io_format >, then
>you are going to run into trouble if it wants a different formatting.

Such a custom object may then have something like the following in its
stream output:

boost::io::ios_pword_saver(stream,index);

// Set stream state, and do output.

That's all. :)

This also ensures that the state is restored properly, even in the presence
of exceptions, something the ++/-- way won't do. Of course, this requires
the pword-index, so one might make the interface more user friendly, and fit
the rest, for example by making the state saver a manipulator, itself.

As I understand, the lifetime of a temporary object extends until the end of
the full expression it's used in, so the following should be well-defined:

std::vector v;

std::cout << composite_save >() << composite_format(...) << v <<
'\n';

This saves the format at the start, and restores it at the end.

An alternative is a named temporary, such as:

composite_save > sentry(stream);

// Set format and do output

> The net effect is that you can optionally add the extra few characters and
prevent
> stomping on other code that is displaying your class.

Exactly. :)

I feel fortunate to have so many competent people around me. This certainly
gives library building a boost. :)


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-05 Thread Terje Slettebø
>From: "Terje Slettebø" <[EMAIL PROTECTED]>

> const int array[3];
>
> std::cout << array;
>
> MSVC 7 - C
> Intel C++ 7  - C
> g++ 3.2   - C
>
> const char array[3];
>
> std::cout << array;
>
> MSVC 7- A (S or C)
> Intel C++ 7 - C
> g++ 3.2  - C
>
> std::cout << "Test";
>
> MSVC 7 - A (S or C)
> Intel 7  - C
> g++ 3.2   - A (S or C)
>
> In order to allow string literals to be used, without ambiguity or the
wrong
> operator being selected, it seems that one needs to overload operator<< on
> something else than T(&)[N]. T[N] isn't an option, either, as this is the
> same as overloading on T *, which means it isn't able to deduce N.
>
> This quandary may be solved by wrapping arrays in an object, which then is
> passed to the overloaded operator<<. For example:
>
> std::cout << wrap_array(array);

I found that boost::ref works for this, as well, so you may use:

char array[3[[3][3];

std::cout << array; // Overloading for this gives wrong handling of string
literals, on all compilers.

std::cout << cref(array); // Ok

For example:

void array3D_test()
{
  char boards[3][3][3]=
  {
{
  {'X','O','X'},
  {'O','X','O'},
  {'X','O','X'}
},
{
  {'X','X','X'},
  {'X','O','X'},
  {'X','X','X'}
},
{
  {'O','X','O'},
  {'X','X','X'},
  {'O','X','O'}
}
  };

  std::cout << composite_format
>("\n|","|\n","|")
<< composite_format
>("---","---","---")
<< composite_format
>("--- Boards ---\n\n","\n\n--- Boards ---","\n\n")
<< boost::cref(boards) << '\n';
}

Output:

--- Boards ---

---
|X|O|X|
---
|O|X|O|
---
|X|O|X|
---

---
|X|X|X|
---
|X|O|X|
---
|X|X|X|
---

---
|O|X|O|
---
|X|X|X|
---
|O|X|O|
---

--- Boards ---

I'll work on a version that works with this.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-05 Thread Terje Slettebø
>From: "Paul A. Bristow" <[EMAIL PROTECTED]>

> This looks really neat - and potentially very useful.

Thanks. :)

> Sadly, array is one of the most interesting cases - so I'm sure I won't be
the
> only one 'watching this space'.

I've looked more into it, and it seems this is a problem not just for MSVC,
but a problem with the current way of doing it, overloading operator<< for
T(&)[N], sinch string literals has the type "const char[N]", as well...

With overloaded operator<< for T(&)[N], and using "std::cout << "Test" ",
g++ gives an ambiguity error, while on Intel C++, it selects the composite
overload, resulting in funny output: It tries to output the null-terminator,
as well, not knowing that for character strings, this is a string
terminator. Besides, it can't really know if the user meant to send a
character string, or a non-null-terminated character array.

It seems the differences is down to subtle implementation differences. Here
are the results, when an overloaded operator<< with T[N] is defined (S -
string-literal operator, C - composite operator (T(&)[N]), A - ambiguous):

const int array[3];

std::cout << array;

MSVC 7 - C
Intel C++ 7  - C
g++ 3.2   - C

const char array[3];

std::cout << array;

MSVC 7- A (S or C)
Intel C++ 7 - C
g++ 3.2  - C

std::cout << "Test";

MSVC 7 - A (S or C)
Intel 7  - C
g++ 3.2   - A (S or C)

In order to allow string literals to be used, without ambiguity or the wrong
operator being selected, it seems that one needs to overload operator<< on
something else than T(&)[N]. T[N] isn't an option, either, as this is the
same as overloading on T *, which means it isn't able to deduce N.

This quandary may be solved by wrapping arrays in an object, which then is
passed to the overloaded operator<<. For example:

std::cout << wrap_array(array);

Comments/suggestions?

> PS composite_format is a bit long, but I can't suggest better.

I know, but I don't know any better, either. I see that Volodya suggests
composite_io in another posting. That's another possibility. Anyway, I guess
what's most important is to get the functionality in place. A default system
may make it easier, as well.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-04 Thread Terje Slettebø
>From: "Jason House" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> > and given this:
> >
> > int main()
> > {
> > char board[3][3]=
> > {
> > {'O','X','O'},
> > {'X','X','O'},
> > {'O','O','X'}
> > };
> >
> > std::cout << io_format("\n|","|\n","|")
> >   << io_format("---","---","---")
> >   << board << '\n';
> > }
> >
> > we get:
> >
> > ---
> > |O|X|O|
> > ---
> > |X|X|O|
> > ---
> > |O|O|X|
> > ---
>
> Hey, that's pretty cool.  I'm glad to see the ability to format items
> inside of a container as well.

I'm glad you like. :) Yes, it applies operator<< recursively, using
overloading, and any format settings for the given type, so for the outer
array, it matches the second format above, and for the inner it matches the
first one.

> It should handle maps and pairs
> reasonably well.  I think that I have the same complaints about this as
> io_manip
>
> The saving of information to the stream means that you can affect all
> future output...
>
> For instance, if you have a type
> map >
>
> and custom_object's stream output uses io_format >, then
> you are going to run into trouble if it wants a different formatting.

Right. That's a consequence of this. As you say too, I don't know any
obvious alternatives, though.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-04 Thread Terje Slettebø
>From: "Paul A. Bristow" <[EMAIL PROTECTED]>

> This looks most useful - potentionally :-(
>
> Alas the two files, test and composite_stream_operators.hpp
>
> http://groups.yahoo.com/group/boost/files/composite_stream_operators/).
>
> won't compile on MSVC 7.0.
>
> test_composite_format.cpp
> test_composite_format.cpp(43) : error C2679: binary '<<' : no operator
found
> which takes a right-hand operand of type 'composite_format' (or there
is no
> acceptable conversion)
> with
> [
> T=char (&)[3]
> ]
>
> and similarly for T=Map
>
> Is the cause/workaround obvious?

Looking at the error messages, and from what I've heard, it may be that it
has problems with template friends (which is what the operator<< is). If
that's the case, the workaround should be very easy - making it a
free-function template.

I did that, now, and it works. :)

At least the vector_pair_test(). The array2D_test() uses a little fancy
code, such as passing the type reference to array as a template parameter,
and it seems MSVC 7.0 has some problems with this. Anyway, that was just to
demonstrate usage with built-in types, as well, such as arrays. I'll look
into it.

There wasn't really any need for it to be a friend function, as it didn't
access any private parts. It was just defined inside the class for
convenience.

I've also tested it on Intel C++ 7.0 in strict mode and g++ 3.2, so the code
should be conformant, at least.

Thanks for the report. I hadn't yet got around to do more portability
testing, but intend to do that, including writing more tests for it. I've
updated the version at Yahoo Groups with the above changes.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-04 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > There are also some other issues: The current version assumes
basic_string
> > for the delimiters. I've found it hard to let it take an arbitrary
string
> > type, as the format-object (which the manipulator,
basic_composite_format,
> > doubles as) stores a format parameterised on type to output and
character
> > type. The latter is so that if multiple streams with different character
> > types are used, they should not use the same format-object..
>
> Is assuming basic_string really a problem?

No, not really. I was just thinking of generality. However, as it is, it
needs the character type, anyway.

> > By the way, just for fun. Adding the following output operator for
arrays,
> > to the header I gave in the previous posting:
>
> > ---
> > |O|X|O|
> > ---
> > |X|X|O|
> > ---
> > |O|O|X|
> > ---
> >
> > "Shall we play a game?" :)
>
> Sure thing :-)

I guess you maybe got the "War Games" reference? :)

> > I've uploaded the new version here
> > (http://groups.yahoo.com/group/boost/files/composite_stream_operators/).
>
> There are two more points:
> 1. Could you put this to the sandbox, too. Yahoogroups is less convenient.

Sure. :)

> 2. I think that we better have separate headers for stl containers, like
> suggested in my original email (, etc). That's
> because I'd like to output maps, but would not like to include 
when
> I need to output a vector.

Heh, just before I got this posting, I had added the following comment in
the header:


///
// The following are just a few examples of output operators, for some of
the
// containers and types in the standard library. These could well be
separated
// in other files. That would also reduce the number of includes.

///

:)

Will do. I'll get back to your other comments, I just need to look more into
how it might be done.


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] Re: io operations for stl containers?

2003-02-04 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
>
> > Incidentally, I've just made a version that does exactly this. :) I've
> > attached it, including a test, with this posting.
>
> I've take a look and I like it -- quite lean and does the work.

Thanks. :)

> I've some concerns, though:
>
> 1. Are "default" breaces/separators possible?  I'd rather not use
> io_format every time I had to output a vector.

Good point. As it is now, it just defaults to empty strings for the
separators. Any idea how to specify such a default? If it's specified in the
header, it may be hard to select one that is sensible for all people.

> 2. Is that good idea to set brace style on vector and vector
> separately? It would increase pword() array, and not sure if this will
> benefit us much. Are nested containers the primary motivation?

Another good point. I guess there isn't any point in separate formats for
different element types, no.

The way it works now is that it instantiates an
basic_composite_format (name changed from
basic_io_format), containing a static function with a static xalloc() index,
for each type to be output. Thus, it's parameterised on a type, not a
partially specified type.

I'll look into this, as well. Partial specialisation, inheriting from a
less-parameterised base comes to mind.

There are also some other issues: The current version assumes basic_string
for the delimiters. I've found it hard to let it take an arbitrary string
type, as the format-object (which the manipulator, basic_composite_format,
doubles as) stores a format parameterised on type to output and character
type. The latter is so that if multiple streams with different character
types are used, they should not use the same format-object..

This means that one must know the character type of the delimiter strings,
in order to parameterise the format object correctly. That's why
basic_string is used, as you then get access to the character type.

By the way, just for fun. Adding the following output operator for arrays,
to the header I gave in the previous posting:


///
// operator<<(stream,T[N])

///

template
std::basic_ostream &operator<<
  (std::basic_ostream &stream,T (&array)[N])
{
  typedef basic_io_format format_type;

  const format_type &format=format_type::format(stream);

  stream << format.start << array[0];

  for(std::size_t i=1;i!=N;++i)
stream << format.delimiter << array[i];

  stream << format.end;

  return stream;
}

and given this:

int main()
{
char board[3][3]=
{
{'O','X','O'},
{'X','X','O'},
{'O','O','X'}
};

std::cout << io_format("\n|","|\n","|")
  << io_format("---","---","---")
  << board << '\n';
}

we get:

---
|O|X|O|
---
|X|X|O|
---
|O|O|X|
---

"Shall we play a game?" :)

By the way, in the first posting, I figured you knew about stream iterators,
so I was a little puzzled, but then it turned out I had just misunderstood
what you meant. Reading it more carefully later, I saw that you did mention
stream operators.

The names and interface is just chosen tentatively, and I'm open to
suggestions for better names. I changed the "*io_format" names to
"*composite_format", as it reflects better what it does, and reduces the
chance for name collision. I didn't want to call it container_format, or
something like that, as it's not restricted to containers, but may output
any composite object, given suitably defined output operators (such as
std::vector, std::pair, arrays, etc.)

Thanks for the feedback.

I've uploaded the new version here
(http://groups.yahoo.com/group/boost/files/composite_stream_operators/).


Regards,

Terje

___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Re: [boost] io operations for stl containers?

2003-02-04 Thread Terje Slettebø
>From: "Vladimir Prus" <[EMAIL PROTECTED]>

> Terje Slettebø wrote:
> >>From: "Vladimir Prus" <[EMAIL PROTECTED]>
> >
> >>after having to output std::vector to stream again and again using
custom
> >>solution, I started to wonder why we don't have a solution in boost.
> >>Does it makes sense to include operators<< for vectors, sets, etc?
>
> >>and so on. There are basically two approaches:
> >>
> >>1. Operators use fixed format: bracked list with commas between values
for
> >>vector, for example.
> >>2. Manipulators are provided to set brackets and separators.
> >>
> >>I had implemented the second approach some time ago, but it turned out
> >> that was overkill. So, 1) looks better now.
>  >
> > If this is done as a library, then I think it's best not to have
hard-coded
> > brackets and separators. One might use an xalloc() value for each type
to
> > output. For example something like:
>
> You see, that's what I have implemented back in 2001. You could change
> braces/separator for each stl container, and it used xalloc()/pword().
> There's one problem though: I don't remember the syntax of brace
> changing, just because I used it a couple of times long ago and then
> stopped. Probably, the scope should be more clearly defined:
>
> Edward Diener wrote:
>  > Al Stevens who writes the C++ column for "Doctor Dobbs Journal" put out
a
>  > persistent template library for C++ containers some time back. It is
>  > probably on the DDJ web site, although I haven't looked there recently.
You
>  > might want to check that out and see what he did. I will readily admit
I
>  > have not had the need to persist container data in my daily programming
but
>  > I can understand others having that need.
>
> Rozental, Gennadiy wrote:
>  > I do not see a way how you could implement solution with better
>  > flexibility/conciseness ratio than copy+ostream_iterator one.
>
> I'm not much interested in persistence (after all, I hope that Robert's
> library will take care of that). Likewise, I never needed arbitrary
> delimiters, etc. But while developing an algorithm for finding k shortest
> paths in a graph, I need to output each path, and have no easy standard
way.
> One might call this output operators are mostly debugging help, but why
not
> have standard debugging help?
>
> > std::cout << boost::io_format(",", "[", "]") <<
> > boost::io_format("","","\n") << list << '\n';
> >
> > This might print:
> >
> > [1, a]
> > [2, b]
> > [3, c]
>
> This example should one case where manipulators are desirable:
>
>  vector< vector > v;
>  cout << v ;
>
> Here, each nested vector better go on a separate line. I suggest:
>
>  cout << multiline << v;
>
> where "multiline" manipulator causes each element of the next output
container
> to go on separate line.

The above io_format<>'s are intended to be manipulators. You could get this
manipulator with:

io_format >("\n","","") multiline;

You could also make it so that this manipulator set the format for any
container, but in cases where you have arbitrary deep nesting of containers
(like in Peter Dimov's posting), it may be better to set the format on a
per-type basis.

Incidentally, I've just made a version that does exactly this. :) I've
attached it, including a test, with this posting.

It's used like this:

int main()
{
typedef std::pair Map;
typedef std::vector MapList;

MapList list;

list.push_back(std::make_pair(1,'A'));
list.push_back(std::make_pair(2,'B'));
list.push_back(std::make_pair(3,'C'));

std::cout << io_format("[","]",",") << io_format("","","\n")
<< list << '\n';
}

Output:

[1,A]
[2,B]
[3,C]

It's a little rough, as it doesn't do proper stream error handling, or
ownership management for the pword object, but it works. Feedback is
welcome.


Regards,

Terje



Test.cpp
Description: Binary data
___
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



  1   2   3   >