a horrible hack to guess the size of boost::format

...without actually including the boost/format.hpp
This saves us a lot of compilation time and debug code size
This commit is contained in:
Fischlurch 2011-12-28 03:19:46 +01:00
parent ce6fbe5f0f
commit 962c789a05
2 changed files with 149 additions and 3 deletions

View file

@ -45,10 +45,10 @@
#ifndef UTIL_FORMAT_STRING_H
#define UTIL_FORMAT_STRING_H
//#include "lib/meta/trait.hpp"
//#include "lib/symbol.hpp"
//#include "lib/util.hpp"
#include "lib/error.hpp"
#include "lib/meta/size-trait.hpp"
#include <string>
//#include <cstring>
@ -89,12 +89,14 @@ namespace util {
class _Fmt
: boost::noncopyable
{
enum{ FORMATTER_SIZE = 100 };
/** size of an internal implementation Buffer */
enum{ FORMATTER_SIZE = lib::meta::SizeTrait::BOOST_FORMAT };
/** @internal buffer to hold a boost::format */
char formatter_[FORMATTER_SIZE];
template<typename VAL, class SEL =void>
struct Converter;

144
src/lib/meta/size-trait.hpp Normal file
View file

@ -0,0 +1,144 @@
/*
SIZE-TRAIT.hpp - helpers and definitions to deal with the size of some known types
Copyright (C) Lumiera.org
2011, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LIB_META_SIZE_TRAIT_H
#define LIB_META_SIZE_TRAIT_H
#include <vector>
#include <string>
namespace lib {
namespace meta {
/**
* A collection of constants to describe the expected size
* of some known classes, without needing to include the
* respective headers. This is an optimisation to improve
* compilation times and/or reduce size of the generated
* object files in debug mode. To get those sizes computed
* in a fairly portable way, but without much overhead,
* we mimic the memory layout of "the real thing"
* with some reasonable simplifications:
* - the size of vectors doesn't really depend on the elements
* - our strings, streams and buffers use just simple chars
*
* \par Interface
* The purpose of this whole construction is to pull off
* some constants based on sizeof expressions:
* - the size of a string
* - the size of a vector
* - the size of a boost::format
*
* @warning this setup is quite fragile and directly relies
* on the implementation layout of the GNU STL and Boost.
* Whenever using this stuff, make sure to place an assertion
* somewhere down in the implementation level to check against
* the size of the real thing.
*/
class SizeTrait
{
//-------------------------------------mimicked-definitions--
typedef std::vector<size_t> Vector;
struct CompatAllocator
: std::allocator<char>
{ };
struct Locale
{
void* _M_impl;
};
template<class T>
struct Optional
{
bool m_initialized_;
T m_storage_;
};
enum IOS_Openmode
{
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
struct BasicStringbuf
{
char * _M_in_beg;
char * _M_in_cur;
char * _M_in_end;
char * _M_out_beg;
char * _M_out_cur;
char * _M_out_end;
Locale _M_buf_locale;
};
struct BasicAltstringbuf
: BasicStringbuf
{
char * putend_;
bool is_allocated_;
IOS_Openmode mode_;
CompatAllocator alloc_;
};
struct BoostFormat
{
Vector items_;
Vector bound_;
int style_;
int cur_arg_;
int num_args_;
bool dumped_;
std::string prefix_;
unsigned char exceptions;
BasicAltstringbuf buf_;
Optional<Locale> loc_;
};
//-------------------------------------mimicked-definitions--
public:/* ===== Interface: size constants ===== */
enum {
STRING = sizeof(std::string)
, VECTOR = sizeof(std::vector<size_t>)
, BOOST_FORMAT = sizeof(BoostFormat)
};
};
}} // namespace lib::meta
#endif