Re: TreeView::append_column_numeric() format?
- From: Carl Nygard <cjnygard fast net>
- To: Murray Cumming <murrayc murrayc com>
- Cc: gtkmm-list gnome org, Ainsley Pereira <gtkmm pebble org uk>
- Subject: Re: TreeView::append_column_numeric() format?
- Date: Mon, 22 Nov 2004 08:25:05 -0500
On Mon, 2004-11-22 at 07:10, Murray Cumming wrote:
> >> So I would like to add another templated convenience method like this:
> >> Gtk::TreeView::append_column_numeric(TreeModelColumn& model,
> >> numeric_format);
> >>
> >> But what's the best way to specify the display format for the number?
> >> I'd
> >> rather not use that nasty printf() style format. Does C++ have something
> >> more suitable?
> >
> > Boost has a "format" object (described here:
> > http://www.boost.org/libs/format/doc/format.html)
>
> Using a formatter object is a good idea, but it seems to mostly use the
> sprintf format anyway, with some extensions.
>
> Also I would feel bad about reproducing so much code in gtkmm. And we
> can't depend on boost because it's not a stable (API or ABI) library yet.
>
> If we find no better alternative to the sprintf format then we could just
> decide to live with
> TreeView::append_column_numeric(TreeModelColumn& column, const
> Glib::ustring& format);
> where format is something like "%.4f" for 4decimal places.
>
> > I'm not suggesting that this actual class should be used, but it's a
> > starting point for ideas. The Gtk::TreeView::append_column_numeric()
> > method could take an object that formats a number (perhaps with a number
> > of
> > simple/common ones supplied). I don't know how all this works underneath
> > though, does it need to translate to printf format for the Gtk+ interface,
> > or does all the formatting happen in the C++ wrapper?
>
> Gtk+ has no equivalent for this. Their whole GtkTreeView API is much more
> unpleasant. And they are probably happy to use C-style sprintf formatting
> for this.
See http://www.3sinc.com/opensource/releases/libcast-0.1.0.tar.gz
This implements a lexical_cast<T> object which uses stringstream to
perform the "cast" of some user-defined object to a string. It's useful
for generating ascii versions of int/float/whatever. It also has
template parameters for "stream policy objects" to allow changing the
stream functions, so you can define policy objects for setting hex,
width, etc. Also has a binder policy to make multiple changes. Comes
with some examples, just no docs at the moment.
I think this could be helpful, either as a helper object passed in the
API, or as a basis for designing a template parameter for user-defined
conversions.
There's also a string_extract template function, which performs in the
opposite direction, given a string and returns an object via
operator>>. This one may not be so well thought out, it was a quick
hack.
Regards,
Carl
Actually, header code is included. There is a specialization for string
objects in a .cxx file, but you'll see what you need in the header, it's
mostly template code.
// -*- c++ -*-
// $RCSfile:$
// lexical_cast.hxx
//
// Copyright (C) 2004 Spatial Software Solutions, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#ifndef CAST_LEXICALCAST
#define CAST_LEXICALCAST
////////////////////////////////////////////////////////////////////
// Includes
#include <string>
#include <strstream>
#include <iomanip>
#include <iostream>
////////////////////////////////////////////////////////////////////
// Class Definition
namespace Cast {
struct cast_policy_none {
void Init(std::ostream& os) const {}
void Cleanup(std::ostream& os) const {}
};
struct cast_policy_hex {
void Init(std::ostream& os) const { os << std::hex;}
void Cleanup(std::ostream& os) const { os << std::dec; }
};
struct cast_policy_quoted {
cast_policy_quoted(char q = '\'') : quote(q) {}
void Init(std::ostream& os) const { os << quote; }
void Cleanup(std::ostream& os) const { os << quote; }
char quote;
};
struct cast_policy_leadzero {
void Init(std::ostream& os) const {
os << std::setfill('0');
}
void Cleanup(std::ostream& os) const {}
};
template <int N>
struct cast_policy_width {
void Init(std::ostream& os) const {
os << std::setw(N);
}
void Cleanup(std::ostream& os) const {}
};
template<typename T, typename U>
struct cast_policy_bind {
cast_policy_bind(const T& t = T(), const U& u = U()) :
first(t), second(u)
{}
void Init(std::ostream& os) const {
first.Init(os);
second.Init(os);
}
void Cleanup(std::ostream& os) const {
second.Cleanup(os);
first.Cleanup(os);
}
T first;
U second;
};
template <typename T, typename U>
cast_policy_bind<T,U> policy_binder(const T& t, const U& u)
{ return cast_policy_bind<T,U>(t, u); }
template <typename T>
std::string lexical_cast(const T& obj)
{
std::ostrstream str;
str << obj << std::ends;
char* buf(str.str());
std::string result(buf);
delete[] buf;
return result;
}
template <typename T, typename P>
std::string lexical_cast(const T& obj, const P& policy = P())
{
std::ostrstream str;
policy.Init(str);
str << obj;
policy.Cleanup(str);
str << std::ends;
char* buf(str.str());
std::string result(buf);
delete[] buf;
return result;
}
std::string lexical_cast(const bool& obj);
template <typename P>
std::string lexical_cast(const bool& obj, const P& policy)
{
std::ostrstream str;
policy.Init(str);
str << (obj ? "YES" : "NO");
policy.Cleanup(str);
str << std::ends;
char* buf(str.str());
std::string result(buf);
delete[] buf;
return result;
}
template <typename T>
std::string upper_cast(const T& obj)
{
std::ostrstream str;
// str << uppercase << obj << std::ends;
str << obj << std::ends;
char* buf(str.str());
// Because uppercase doesn't seem to work
{
for(char* it = buf; *it; ++it){
if((*it <= 'z') && (*it >= 'a'))
*it += 'A' - 'a';
}
}
std::string result(buf);
delete[] buf;
return result;
}
template <typename T>
T string_extract(const std::string& str)
{
std::istrstream s(str.c_str(), str.length());
T result;
s >> result;
return result;
}
} // namespace
#endif // CAST_LEXICALCAST
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]