Compare commits

...

14 Commits

Author SHA1 Message Date
nobody
bf6d08b73b This commit was manufactured by cvs2svn to create branch 'SPIRIT_1_6'.
[SVN r23968]
2004-07-23 02:16:28 +00:00
Robert Ramey
40a44d6810 cleanup and improved portability
[SVN r23850]
2004-07-20 20:41:19 +00:00
Dave Abrahams
b6dee6532e Fixed postfix increment for incrementable and single-pass iterator facade
[SVN r23456]
2004-07-12 03:18:49 +00:00
Robert Ramey
700efc2873 initial checkin
[SVN r23434]
2004-07-11 01:26:33 +00:00
Joaquín M. López Muñoz
ec1d526862 stricter check in is_partial_std_allocator
[SVN r23067]
2004-06-09 13:58:56 +00:00
Joaquín M. López Muñoz
f20d50a741 renamed to allocator_utilities.hpp
[SVN r23061]
2004-06-09 10:18:28 +00:00
Joaquín M. López Muñoz
165c7e29fa was allocator.hpp
[SVN r23060]
2004-06-09 10:17:41 +00:00
Joaquín M. López Muñoz
acea9bf9fa fixed include guard clash with boost/regex/config/allocator.hpp
[SVN r23006]
2004-06-02 15:54:10 +00:00
Joaquín M. López Muñoz
fc82a4b926 moved from boost/multi_index/detail
[SVN r23004]
2004-06-02 14:35:30 +00:00
John Maddock
fefc312df8 Moved detail/allocator.hpp into regex directory.
[SVN r22967]
2004-05-28 12:21:44 +00:00
Gennaro Prota
42bfb20e4b new license reference
[SVN r22834]
2004-05-16 09:17:55 +00:00
Gennaro Prota
19cd8815b6 added Borland workaround
[SVN r22770]
2004-05-09 08:58:03 +00:00
Joaquín M. López Muñoz
a00196977f initial commit
[SVN r22759]
2004-05-07 10:44:23 +00:00
Gennaro Prota
5f07eb294f new file (needed by dynamic_bitset)
[SVN r22651]
2004-04-18 09:15:08 +00:00
7 changed files with 631 additions and 307 deletions

View File

@@ -1,281 +0,0 @@
/*
*
* Copyright (c) 2001
* Dr John Maddock
*
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef BOOST_DETAIL_ALLOCATOR_HPP
#define BOOST_DETAIL_ALLOCATOR_HPP
#include <boost/config.hpp>
#include <cstdlib>
#include <new>
#include <assert.h>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::ptrdiff_t;
using ::size_t;
}
#endif
// see if we have SGI alloc class:
#if defined(BOOST_NO_STD_ALLOCATOR) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) || defined(__GLIBCPP__) || defined(__STL_CONFIG_H))
# define BOOST_HAVE_SGI_ALLOCATOR
# include <memory>
# if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
namespace boost{ namespace detail{
typedef std::__sgi_alloc alloc_type;
}}
# else
namespace boost{ namespace detail{
typedef std::alloc alloc_type;
}}
# endif
#endif
namespace boost{ namespace detail{
template <class T>
void allocator_construct(T* p, const T& t)
{ new (p) T(t); }
template <class T>
void allocator_destroy(T* p)
{
(void)p; // warning suppression
p->~T();
}
} }
#if !defined(BOOST_NO_STD_ALLOCATOR)
#include <memory>
#define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T >
namespace boost{ namespace detail{
template <class T, class A>
struct rebind_allocator
{
typedef typename A::template rebind<T> binder;
typedef typename binder::other type;
};
} // namespace detail
} // namespace boost
#elif !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__SUNPRO_CC)
// no std::allocator, but the compiler supports the necessary syntax,
// write our own allocator instead:
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator< T >
namespace boost{ namespace detail{
template <class T>
class allocator
{
public:
typedef T value_type;
typedef value_type * pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template <class U>
struct rebind
{
typedef allocator<U> other;
};
allocator(){}
template <class U>
allocator(const allocator<U>&){}
allocator(const allocator&){}
template <class U>
allocator& operator=(const allocator<U>&)
{ return *this; }
~allocator(){}
pointer address(reference x) { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer allocate(size_type n, const void* = 0)
{
#ifdef BOOST_HAVE_SGI_ALLOCATOR
return n != 0 ?
reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
: 0;
#else
return n != 0 ?
reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
: 0;
#endif
}
void deallocate(pointer p, size_type n)
{
#ifdef BOOST_HAVE_SGI_ALLOCATOR
assert( (p == 0) == (n == 0) );
if (p != 0)
alloc_type::deallocate((void*)p, n);
#else
assert( (p == 0) == (n == 0) );
if (p != 0)
::operator delete((void*)p);
#endif
}
size_type max_size() const
{ return size_t(-1) / sizeof(value_type); }
void construct(pointer p, const T& val) const
{ allocator_construct(p, val); }
void destroy(pointer p) const
{ allocator_destroy(p); }
};
template <class T, class A>
struct rebind_allocator
{
typedef typename A::template rebind<T> binder;
typedef typename binder::other type;
};
} // namespace detail
} // namespace boost
#else
// no std::allocator, use workaround version instead,
// each allocator class must derive from a base class
// that allocates blocks of bytes:
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
namespace boost{ namespace detail{
class simple_alloc
{
public:
typedef void value_type;
typedef value_type * pointer;
typedef const void* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
simple_alloc(){}
simple_alloc(const simple_alloc&){}
~simple_alloc(){}
pointer allocate(size_type n, const void* = 0)
{
#ifdef BOOST_HAVE_SGI_ALLOCATOR
return n != 0 ?
reinterpret_cast<pointer>(alloc_type::allocate(n))
: 0;
#else
return n != 0 ?
reinterpret_cast<pointer>(::operator new(n))
: 0;
#endif
}
void deallocate(pointer p, size_type n)
{
#ifdef BOOST_HAVE_SGI_ALLOCATOR
assert( (p == 0) == (n == 0) );
if (p != 0)
alloc_type::deallocate((void*)p, n);
#else
assert( (p == 0) == (n == 0) );
if (p != 0)
::operator delete((void*)p);
#endif
}
};
template <class T, class Base>
class allocator_adapter : public Base
{
public:
typedef T value_type;
typedef value_type * pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef Base base_type;
allocator_adapter(){}
allocator_adapter(const base_type& x) : Base(x){}
allocator_adapter& operator=(const base_type& x)
{
*(static_cast<base_type*>(this)) = x;
return *this;
}
~allocator_adapter(){}
pointer address(reference x) { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer allocate(size_type n, const void* = 0)
{
return n != 0 ?
reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
: 0;
}
void deallocate(pointer p, size_type n)
{
assert( (p == 0) == (n == 0) );
if (p != 0)
static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
}
size_type max_size() const
{ return size_t(-1) / sizeof(value_type); }
void construct(pointer p, const T& val) const
{ allocator_construct(p, val); }
void destroy(pointer p) const
{ allocator_destroy(p); }
};
template <class T, class A>
struct rebind_allocator
{
typedef allocator_adapter<T, typename A::base_type> type;
};
} // namespace detail
} // namespace boost
#endif
#endif // include guard

View File

@@ -0,0 +1,178 @@
/* Copyright 2003-2004 Joaqu<71>n M L<>pez Mu<4D>oz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See Boost website at http://www.boost.org/
*/
#ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
#define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/mpl/aux_/msvc_never_true.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <cstddef>
#include <memory>
#include <new>
namespace boost{
namespace detail{
/* Allocator adaption layer. Some stdlibs provide allocators without rebind
* and template ctors. These facilities are simulated with the external
* template class rebind_to and the aid of partial_std_allocator_wrapper.
*/
namespace allocator{
/* partial_std_allocator_wrapper inherits the functionality of a std
* allocator while providing a templatized ctor.
*/
template<typename Type>
class partial_std_allocator_wrapper:public std::allocator<Type>
{
public:
partial_std_allocator_wrapper(){};
template<typename Other>
partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
#if defined(BOOST_DINKUMWARE_STDLIB)
/* Dinkumware guys didn't provide a means to call allocate() without
* supplying a hint, in disagreement with the standard.
*/
Type* allocate(std::size_t n,const void* hint=0)
{
std::allocator<Type>& a=*this;
return a.allocate(n,hint);
}
#endif
};
/* Detects whether a given allocator belongs to a defective stdlib not
* having the required member templates.
* Note that it does not suffice to check the Boost.Config stdlib
* macros, as the user might have passed a custom, compliant allocator.
* The checks also considers partial_std_allocator_wrapper to be
* a standard defective allocator.
*/
#if defined(BOOST_NO_STD_ALLOCATOR)&&\
(defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
template<typename Allocator>
struct is_partial_std_allocator
{
BOOST_STATIC_CONSTANT(bool,
value=
(is_same<
std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
Allocator
>::value)||
(is_same<
partial_std_allocator_wrapper<
BOOST_DEDUCED_TYPENAME Allocator::value_type>,
Allocator
>::value));
};
#else
template<typename Allocator>
struct is_partial_std_allocator
{
BOOST_STATIC_CONSTANT(bool,value=false);
};
#endif
/* rebind operations for defective std allocators */
template<typename Allocator,typename Type>
struct partial_std_allocator_rebind_to
{
typedef partial_std_allocator_wrapper<Type> type;
};
/* rebind operation in all other cases */
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
/* Workaround for a problem in MSVC with dependent template typedefs
* when doing rebinding of allocators.
* Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
*/
template<typename Allocator>
struct rebinder
{
template<bool> struct fake_allocator:Allocator{};
template<> struct fake_allocator<true>
{
template<typename Type> struct rebind{};
};
template<typename Type>
struct result:
fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
template rebind<Type>
{
};
};
#else
template<typename Allocator>
struct rebinder
{
template<typename Type>
struct result:Allocator::BOOST_NESTED_TEMPLATE rebind<Type>
{
};
};
#endif
template<typename Allocator,typename Type>
struct compliant_allocator_rebind_to
{
typedef typename rebinder<Allocator>::
BOOST_NESTED_TEMPLATE result<Type>::other type;
};
/* rebind front-end */
template<typename Allocator,typename Type>
struct rebind_to:
mpl::apply_if_c<
is_partial_std_allocator<Allocator>::value,
partial_std_allocator_rebind_to<Allocator,Type>,
compliant_allocator_rebind_to<Allocator,Type>
>
{
};
/* allocator-independent versions of construct and destroy */
template<typename Type>
void construct(void* p,const Type& t)
{
new (p) Type(t);
}
template<typename Type>
void destroy(const Type* p)
{
p->~Type();
}
} /* namespace boost::detail::allocator */
} /* namespace boost::detail */
} /* namespace boost */
#endif

View File

@@ -19,14 +19,28 @@ namespace boost { namespace detail {
// This namespace ensures that ADL doesn't mess things up.
namespace is_incrementable_
{
// a type returned from operator++ when no increment is found in the
// type's own namespace
struct tag {};
// any soaks up implicit conversions and makes the following
// operator++ less-preferred than any other such operator which
// operator++ less-preferred than any other such operator that
// might be found via ADL.
struct any { template <class T> any(T const&); };
tag operator++(any const&);
// This is a last-resort operator++ for when none other is found
tag operator++(any const&);
tag operator++(any const&,int);
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
|| BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# define BOOST_comma(a,b) (a)
# else
// In case an operator++ is found that returns void, we'll use ++x,0
tag operator,(tag,int);
# define BOOST_comma(a,b) (a,b)
# endif
// two check overloads help us identify which operator++ was picked
char (& check(tag) )[2];
@@ -35,36 +49,41 @@ namespace is_incrementable_
template <class T>
struct
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
impl
# else
is_incrementable
# endif
struct impl
{
static typename remove_cv<T>::type& x;
BOOST_STATIC_CONSTANT(
bool
, value = sizeof(is_incrementable_::check(++x)) == 1
, value = sizeof(is_incrementable_::check(BOOST_comma(++x,0))) == 1
);
};
typedef mpl::bool_<(
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
::boost::detail::is_incrementable_::is_incrementable<T>::
# endif
value)> type;
template <class T>
struct postfix_impl
{
static typename remove_cv<T>::type& x;
BOOST_STATIC_CONSTANT(
bool
, value = sizeof(is_incrementable_::check(BOOST_comma(x++,0))) == 1
);
};
}
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# undef BOOST_comma
template <class T>
struct is_incrementable : is_incrementable_::impl<T>
struct is_incrementable
: mpl::bool_< ::boost::detail::is_incrementable_::impl<T>::value>
{
};
template <class T>
struct is_postfix_incrementable
: mpl::bool_< ::boost::detail::is_incrementable_::postfix_impl<T>::value>
{
};
# else
using is_incrementable_::is_incrementable;
# endif
}} // namespace boost::detail

View File

@@ -0,0 +1,87 @@
#ifndef BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_
#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
//----------------------------------------------------------------------
// (C) Copyright 2004 Pavel Vozenilek.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//
// This file contains helper macros used when exception support may be
// disabled (as indicated by macro BOOST_NO_EXCEPTIONS).
//
// Before picking up these macros you may consider using RAII techniques
// to deal with exceptions - their syntax can be always the same with
// or without exception support enabled.
//
/* Example of use:
void foo() {
BOOST_TRY {
...
} BOOST_CATCH(const std::bad_alloc&) {
...
BOOST_RETHROW
} BOOST_CATCH(const std::exception& e) {
...
}
BOOST_CATCH_END
}
With exception support enabled it will expand into:
void foo() {
{ try {
...
} catch (const std::bad_alloc&) {
...
throw;
} catch (const std::exception& e) {
...
}
}
}
With exception support disabled it will expand into:
void foo() {
{ if(true) {
...
} else if (false) {
...
} else if (false) {
...
}
}
}
*/
//----------------------------------------------------------------------
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#if !(defined BOOST_NO_EXCEPTIONS)
# define BOOST_TRY { try
# define BOOST_CATCH(x) catch(x)
# define BOOST_RETHROW throw;
# define BOOST_CATCH_END }
#else
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_TRY { if ("")
# define BOOST_CATCH(x) else if (!"")
# else
# define BOOST_TRY { if (true)
# define BOOST_CATCH(x) else if (false)
# endif
# define BOOST_RETHROW
# define BOOST_CATCH_END }
#endif
#endif

View File

@@ -1,9 +1,12 @@
// (C) Copyright Gennaro Prota 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// -------------------------------------
//
// (C) Copyright Gennaro Prota 2003.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// ------------------------------------------------------
#ifndef BOOST_NON_TYPE_HPP_GP_20030417
#define BOOST_NON_TYPE_HPP_GP_20030417

View File

@@ -0,0 +1,113 @@
// -------------------------------------
// integer_log2.hpp
//
// Gives the integer part of the logarithm, in base 2, of a
// given number. Behavior is undefined if the argument is <= 0.
//
//
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// ------------------------------------------------------
#ifndef BOOST_INTEGER_LOG2_HPP_GP_20030301
#define BOOST_INTEGER_LOG2_HPP_GP_20030301
#include <cassert>
#include <climits> // actually used for Borland only
#include "boost/limits.hpp"
#include "boost/config.hpp"
namespace boost {
namespace detail {
template <typename T>
int integer_log2_impl(T x, int n) {
int result = 0;
while (x != 1) {
const T t = x >> n;
if (t) {
result += n;
x = t;
}
n /= 2;
}
return result;
}
// helper to find the maximum power of two
// less than p (more involved than necessary,
// to avoid PTS)
//
template <int p, int n>
struct max_pow2_less {
enum { c = 2*n < p };
BOOST_STATIC_CONSTANT(int, value =
c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
};
template <>
struct max_pow2_less<0, 0> {
BOOST_STATIC_CONSTANT(int, value = 0);
};
// this template is here just for Borland :(
// we could simply rely on numeric_limits but sometimes
// Borland tries to use numeric_limits<const T>, because
// of its usual const-related problems in argument deduction
// - gps
template <typename T>
struct width {
#ifdef __BORLANDC__
BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
#else
BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
#endif
};
} // detail
// ---------
// integer_log2
// ---------------
//
template <typename T>
int integer_log2(T x) {
assert(x > 0);
const int n = detail::max_pow2_less<
detail::width<T> :: value, 4
> :: value;
return detail::integer_log2_impl(x, n);
}
}
#endif // include guard

View File

@@ -0,0 +1,205 @@
#ifndef BOOST_UTF8_CODECVT_FACET_HPP
#define BOOST_UTF8_CODECVT_FACET_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// utf8_codecvt_facet.hpp
// Copyright <20> 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its suitability
// for any purpose.
// Note:(Robert Ramey). I have made the following alterations in the original
// code.
// a) Rendered utf8_codecvt<wchar_t, char> with using templates
// b) Move longer functions outside class definition to prevent inlining
// and make code smaller
// c) added on a derived class to permit translation to/from current
// locale to utf8
// See http://www.boost.org for updates, documentation, and revision history.
// archives stored as text - note these ar templated on the basic
// stream templates to accommodate wide (and other?) kind of characters
//
// note the fact that on libraries without wide characters, ostream is
// is not a specialization of basic_ostream which in fact is not defined
// in such cases. So we can't use basic_ostream<OStream::char_type> but rather
// use two template parameters
//
// utf8_codecvt_facet
// This is an implementation of a std::codecvt facet for translating
// from UTF-8 externally to UCS-4. Note that this is not tied to
// any specific types in order to allow customization on platforms
// where wchar_t is not big enough.
//
// NOTES: The current implementation jumps through some unpleasant hoops in
// order to deal with signed character types. As a std::codecvt_base::result,
// it is necessary for the ExternType to be convertible to unsigned char.
// I chose not to tie the extern_type explicitly to char. But if any combination
// of types other than <wchar_t,char_t> is used, then std::codecvt must be
// specialized on those types for this to work.
#include <locale>
#if defined(__COMO__)
namespace std{
using ::mbstate_t;
} // namespace std
#elif (defined(BOOST_MSVC) && (_MSC_VER <= 1300))
namespace std{
using ::mbstate_t;
} // namespace std
#elif defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::codecvt;
using ::mbstate_t;
} // namespace std
#endif
// maximum lenght of a multibyte string
#define MB_LENGTH_MAX 8
struct utf8_codecvt_facet_wchar_t :
public std::codecvt<wchar_t, char, std::mbstate_t>
{
public:
explicit utf8_codecvt_facet_wchar_t(size_t no_locale_manage = 0)
: std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
{}
protected:
virtual std::codecvt_base::result do_in(
std::mbstate_t& state,
const char * from,
const char * from_end,
const char * & from_next,
wchar_t * to,
wchar_t * to_end,
wchar_t*& to_next
) const;
virtual std::codecvt_base::result do_out(
std::mbstate_t & state, const wchar_t * from,
const wchar_t * from_end, const wchar_t* & from_next,
char * to, char * to_end, char * & to_next
) const;
bool invalid_continuing_octet(unsigned char octet_1) const {
return (octet_1 < 0x80|| 0xbf< octet_1);
}
bool invalid_leading_octet(unsigned char octet_1) const {
return (0x7f < octet_1 && octet_1 < 0xc0) ||
(octet_1 > 0xfd);
}
// continuing octets = octets except for the leading octet
static unsigned int get_cont_octet_count(unsigned char lead_octet) {
return get_octet_count(lead_octet) - 1;
}
static unsigned int get_octet_count(unsigned char lead_octet);
// How many "continuing octets" will be needed for this word
// == total octets - 1.
int get_cont_octet_out_count(wchar_t word) const ;
virtual bool do_always_noconv() const throw() { return false; }
// UTF-8 isn't really stateful since we rewind on partial conversions
virtual std::codecvt_base::result do_unshift(
std::mbstate_t&,
char * from,
char * to,
char * & next
) const{
next = from;
return ok;
}
virtual int do_encoding() const throw() {
const int variable_byte_external_encoding=0;
return variable_byte_external_encoding;
}
// How many char objects can I process to get <= max_limit
// wchar_t objects?
virtual int do_length(
const std::mbstate_t &,
const char * from,
const char * from_end,
size_t max_limit
) const throw();
// Largest possible value do_length(state,from,from_end,1) could return.
virtual int do_max_length() const throw () {
return 6; // largest UTF-8 encoding of a UCS-4 character
}
};
#if 0 // not used - incorrect in any case
// Robert Ramey - use the above to make a code converter from multi-byte
// char strings to utf8 encoding
struct utf8_codecvt_facet_char : public utf8_codecvt_facet_wchar_t
{
typedef utf8_codecvt_facet_wchar_t base_class;
public:
explicit utf8_codecvt_facet_char(size_t no_locale_manage=0)
: base_class(no_locale_manage)
{}
protected:
virtual std::codecvt_base::result do_in(
std::mbstate_t & state,
const char * from,
const char * from_end,
const char * & from_next,
char * to,
char * to_end,
char * & to_next
) const;
virtual std::codecvt_base::result do_out(
std::mbstate_t & state,
const char * from,
const char * from_end,
const char* & from_next,
char * to,
char * to_end,
char * & to_next
) const;
// How many char objects can I process to get <= max_limit
// char objects?
virtual int do_length(
const std::mbstate_t&,
const char * from,
const char * from_end,
size_t max_limit
) const;
};
#endif
template<class Internal, class External>
struct utf8_codecvt_facet
{};
template<>
struct utf8_codecvt_facet<wchar_t, char>
: public utf8_codecvt_facet_wchar_t
{};
#if 0
template<>
struct utf8_codecvt_facet<char, char>
: public utf8_codecvt_facet_char
{};
#endif
#endif // BOOST_UTF8_CODECVT_FACET_HPP