mirror of
https://github.com/boostorg/detail.git
synced 2025-06-28 21:41:07 +02:00
Compare commits
1 Commits
boost-1.45
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
b5c12a40a9 |
@ -1,100 +0,0 @@
|
|||||||
//-----------------------------------------------------------------------------
|
|
||||||
// boost blank.hpp header file
|
|
||||||
// See http://www.boost.org for updates, documentation, and revision history.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright (c) 2003
|
|
||||||
// Eric Friedman
|
|
||||||
//
|
|
||||||
// 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_BLANK_HPP
|
|
||||||
#define BOOST_BLANK_HPP
|
|
||||||
|
|
||||||
#include "boost/blank_fwd.hpp"
|
|
||||||
|
|
||||||
#include <iosfwd> // for std::basic_ostream forward declare
|
|
||||||
|
|
||||||
#include "boost/detail/templated_streams.hpp"
|
|
||||||
#include "boost/mpl/bool.hpp"
|
|
||||||
#include "boost/type_traits/is_empty.hpp"
|
|
||||||
#include "boost/type_traits/is_pod.hpp"
|
|
||||||
#include "boost/type_traits/is_stateless.hpp"
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
struct blank
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// type traits specializations
|
|
||||||
//
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_pod< blank >
|
|
||||||
: mpl::true_
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_empty< blank >
|
|
||||||
: mpl::true_
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_stateless< blank >
|
|
||||||
: mpl::true_
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// relational operators
|
|
||||||
//
|
|
||||||
|
|
||||||
inline bool operator==(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const blank&, const blank&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// streaming support
|
|
||||||
//
|
|
||||||
BOOST_TEMPLATED_STREAM_TEMPLATE(E,T)
|
|
||||||
inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
|
|
||||||
BOOST_TEMPLATED_STREAM(ostream, E,T)& out
|
|
||||||
, const blank&
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// (output nothing)
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_BLANK_HPP
|
|
@ -1,22 +0,0 @@
|
|||||||
//-----------------------------------------------------------------------------
|
|
||||||
// boost blank_fwd.hpp header file
|
|
||||||
// See http://www.boost.org for updates, documentation, and revision history.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright (c) 2003
|
|
||||||
// Eric Friedman
|
|
||||||
//
|
|
||||||
// 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_BLANK_FWD_HPP
|
|
||||||
#define BOOST_BLANK_FWD_HPP
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
struct blank;
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_BLANK_FWD_HPP
|
|
@ -1,41 +0,0 @@
|
|||||||
// boost/cstdlib.hpp header ------------------------------------------------//
|
|
||||||
|
|
||||||
// Copyright Beman Dawes 2001. 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 http://www.boost.org/libs/utility/cstdlib.html for documentation.
|
|
||||||
|
|
||||||
// Revision History
|
|
||||||
// 26 Feb 01 Initial version (Beman Dawes)
|
|
||||||
|
|
||||||
#ifndef BOOST_CSTDLIB_HPP
|
|
||||||
#define BOOST_CSTDLIB_HPP
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
// The intent is to propose the following for addition to namespace std
|
|
||||||
// in the C++ Standard Library, and to then deprecate EXIT_SUCCESS and
|
|
||||||
// EXIT_FAILURE. As an implementation detail, this header defines the
|
|
||||||
// new constants in terms of EXIT_SUCCESS and EXIT_FAILURE. In a new
|
|
||||||
// standard, the constants would be implementation-defined, although it
|
|
||||||
// might be worthwhile to "suggest" (which a standard is allowed to do)
|
|
||||||
// values of 0 and 1 respectively.
|
|
||||||
|
|
||||||
// Rationale for having multiple failure values: some environments may
|
|
||||||
// wish to distinguish between different classes of errors.
|
|
||||||
// Rationale for choice of values: programs often use values < 100 for
|
|
||||||
// their own error reporting. Values > 255 are sometimes reserved for
|
|
||||||
// system detected errors. 200/201 were suggested to minimize conflict.
|
|
||||||
|
|
||||||
const int exit_success = EXIT_SUCCESS; // implementation-defined value
|
|
||||||
const int exit_failure = EXIT_FAILURE; // implementation-defined value
|
|
||||||
const int exit_exception_failure = 200; // otherwise uncaught exception
|
|
||||||
const int exit_test_failure = 201; // report_error or
|
|
||||||
// report_critical_error called.
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
#ifndef INDIRECT_REFERENCE_DWA200415_HPP
|
|
||||||
# define INDIRECT_REFERENCE_DWA200415_HPP
|
|
||||||
|
|
||||||
//
|
|
||||||
// Copyright David Abrahams 2004. 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)
|
|
||||||
//
|
|
||||||
// typename indirect_reference<P>::type provides the type of *p.
|
|
||||||
//
|
|
||||||
// http://www.boost.org/libs/iterator/doc/pointee.html
|
|
||||||
//
|
|
||||||
|
|
||||||
# include <boost/detail/is_incrementable.hpp>
|
|
||||||
# include <boost/iterator/iterator_traits.hpp>
|
|
||||||
# include <boost/type_traits/remove_cv.hpp>
|
|
||||||
# include <boost/mpl/eval_if.hpp>
|
|
||||||
# include <boost/pointee.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <class P>
|
|
||||||
struct smart_ptr_reference
|
|
||||||
{
|
|
||||||
typedef typename boost::pointee<P>::type& type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class P>
|
|
||||||
struct indirect_reference
|
|
||||||
: mpl::eval_if<
|
|
||||||
detail::is_incrementable<P>
|
|
||||||
, iterator_reference<P>
|
|
||||||
, detail::smart_ptr_reference<P>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // INDIRECT_REFERENCE_DWA200415_HPP
|
|
@ -1,27 +0,0 @@
|
|||||||
// -------------------------------------
|
|
||||||
//
|
|
||||||
// (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
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Just a simple "envelope" for non-type template parameters. Useful
|
|
||||||
// to work around some MSVC deficiencies.
|
|
||||||
|
|
||||||
template <typename T, T n>
|
|
||||||
struct non_type { };
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // include guard
|
|
@ -1,16 +0,0 @@
|
|||||||
// -*- C++ -*- forwarding header.
|
|
||||||
// (C) Copyright Jeremy Siek 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_CSTDDEF_HPP
|
|
||||||
#define BOOST_CSTDDEF_HPP
|
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
|
||||||
# include <stddef.h>
|
|
||||||
#else
|
|
||||||
# include <cstddef>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,111 +0,0 @@
|
|||||||
// (C) Copyright Jeremy Siek 2000.
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// The ct_if implementation that avoids partial specialization is
|
|
||||||
// based on the IF class by Ulrich W. Eisenecker and Krzysztof
|
|
||||||
// Czarnecki.
|
|
||||||
|
|
||||||
#ifndef BOOST_CT_IF_HPP
|
|
||||||
#define BOOST_CT_IF_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
/*
|
|
||||||
There is a bug in the Borland compiler with regards to using
|
|
||||||
integers to specialize templates. This made it hard to use ct_if in
|
|
||||||
the graph library. Changing from 'ct_if' to 'ct_if_t' fixed the
|
|
||||||
problem.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <boost/type_traits/integral_constant.hpp> // true_type and false_type
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
struct ct_if_error { };
|
|
||||||
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_and { typedef false_type type; };
|
|
||||||
template <> struct ct_and<true_type,true_type> { typedef true_type type; };
|
|
||||||
|
|
||||||
template <class A> struct ct_not { typedef ct_if_error type; };
|
|
||||||
template <> struct ct_not<true_type> { typedef false_type type; };
|
|
||||||
template <> struct ct_not<false_type> { typedef true_type type; };
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
|
|
||||||
// agurt, 15/sep/02: in certain cases Borland has problems with
|
|
||||||
// choosing the right 'ct_if' specialization even though 'cond'
|
|
||||||
// _does_ equal '1'; the easiest way to fix it is to make first
|
|
||||||
// 'ct_if' non-type template parameter boolean.
|
|
||||||
#if !defined(__BORLANDC__)
|
|
||||||
template <bool cond, class A, class B>
|
|
||||||
struct ct_if { typedef ct_if_error type; };
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_if<true, A, B> { typedef A type; };
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_if<false, A, B> { typedef B type; };
|
|
||||||
#else
|
|
||||||
template <bool cond, class A, class B>
|
|
||||||
struct ct_if { typedef A type; };
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_if<false, A, B> { typedef B type; };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class cond, class A, class B>
|
|
||||||
struct ct_if_t { typedef ct_if_error type; };
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_if_t<true_type, A, B> { typedef A type; };
|
|
||||||
template <class A, class B>
|
|
||||||
struct ct_if_t<false_type, A, B> { typedef B type; };
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <int condition, class A, class B> struct IF;
|
|
||||||
template <int condition> struct SlectSelector;
|
|
||||||
struct SelectFirstType;
|
|
||||||
struct SelectSecondType;
|
|
||||||
|
|
||||||
struct SelectFirstType {
|
|
||||||
template<class A, class B>
|
|
||||||
struct Template { typedef A type; };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SelectSecondType {
|
|
||||||
template<class A, class B>
|
|
||||||
struct Template { typedef B type; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int condition>
|
|
||||||
struct SlectSelector {
|
|
||||||
typedef SelectFirstType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct SlectSelector<0> {
|
|
||||||
typedef SelectSecondType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<int condition, class A, class B>
|
|
||||||
struct ct_if
|
|
||||||
{
|
|
||||||
typedef typename detail::SlectSelector<condition>::type Selector;
|
|
||||||
typedef typename Selector::template Template<A, B>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class cond, class A, class B>
|
|
||||||
struct ct_if_t {
|
|
||||||
typedef typename ct_if<cond::value, A, B>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_CT_IF_HPP
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
|||||||
// -------------------------------------
|
|
||||||
// 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
|
|
@ -1,18 +0,0 @@
|
|||||||
// (C) Copyright David Abrahams 2001.
|
|
||||||
// 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_TYPE_DWA20010120_HPP
|
|
||||||
# define BOOST_TYPE_DWA20010120_HPP
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Just a simple "type envelope". Useful in various contexts, mostly to work
|
|
||||||
// around some MSVC deficiencies.
|
|
||||||
template <class T>
|
|
||||||
struct type {};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOST_TYPE_DWA20010120_HPP
|
|
@ -1,29 +0,0 @@
|
|||||||
// Boost.Signals library
|
|
||||||
|
|
||||||
// Copyright Douglas Gregor 2001-2003. 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)
|
|
||||||
|
|
||||||
// For more information, see http://www.boost.org/libs/signals
|
|
||||||
|
|
||||||
#ifndef BOOST_VISIT_EACH_HPP
|
|
||||||
#define BOOST_VISIT_EACH_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
template<typename Visitor, typename T>
|
|
||||||
inline void visit_each(Visitor& visitor, const T& t, long)
|
|
||||||
{
|
|
||||||
visitor(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Visitor, typename T>
|
|
||||||
inline void visit_each(Visitor& visitor, const T& t)
|
|
||||||
{
|
|
||||||
visit_each(visitor, t, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOST_VISIT_EACH_HPP
|
|
@ -1,269 +0,0 @@
|
|||||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
|
||||||
// utf8_codecvt_facet.cpp
|
|
||||||
|
|
||||||
// Copyright <20> 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
|
|
||||||
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// Please see the comments in <boost/detail/utf8_codecvt_facet.hpp> to
|
|
||||||
// learn how this file should be used.
|
|
||||||
|
|
||||||
#include <boost/detail/utf8_codecvt_facet.hpp>
|
|
||||||
|
|
||||||
#include <cstdlib> // for multi-byte converson routines
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
// If we don't have wstring, then Unicode support
|
|
||||||
// is not available anyway, so we don't need to even
|
|
||||||
// compiler this file. This also fixes the problem
|
|
||||||
// with mingw, which can compile this file, but will
|
|
||||||
// generate link error when building DLL.
|
|
||||||
#ifndef BOOST_NO_STD_WSTRING
|
|
||||||
|
|
||||||
BOOST_UTF8_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
|
||||||
// implementation for wchar_t
|
|
||||||
|
|
||||||
// Translate incoming UTF-8 into UCS-4
|
|
||||||
std::codecvt_base::result utf8_codecvt_facet::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 {
|
|
||||||
// Basic algorithm: The first octet determines how many
|
|
||||||
// octets total make up the UCS-4 character. The remaining
|
|
||||||
// "continuing octets" all begin with "10". To convert, subtract
|
|
||||||
// the amount that specifies the number of octets from the first
|
|
||||||
// octet. Subtract 0x80 (1000 0000) from each continuing octet,
|
|
||||||
// then mash the whole lot together. Note that each continuing
|
|
||||||
// octet only uses 6 bits as unique values, so only shift by
|
|
||||||
// multiples of 6 to combine.
|
|
||||||
while (from != from_end && to != to_end) {
|
|
||||||
|
|
||||||
// Error checking on the first octet
|
|
||||||
if (invalid_leading_octet(*from)){
|
|
||||||
from_next = from;
|
|
||||||
to_next = to;
|
|
||||||
return std::codecvt_base::error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first octet is adjusted by a value dependent upon
|
|
||||||
// the number of "continuing octets" encoding the character
|
|
||||||
const int cont_octet_count = get_cont_octet_count(*from);
|
|
||||||
const wchar_t octet1_modifier_table[] = {
|
|
||||||
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
|
|
||||||
};
|
|
||||||
|
|
||||||
// The unsigned char conversion is necessary in case char is
|
|
||||||
// signed (I learned this the hard way)
|
|
||||||
wchar_t ucs_result =
|
|
||||||
(unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
|
|
||||||
|
|
||||||
// Invariants :
|
|
||||||
// 1) At the start of the loop, 'i' continuing characters have been
|
|
||||||
// processed
|
|
||||||
// 2) *from points to the next continuing character to be processed.
|
|
||||||
int i = 0;
|
|
||||||
while(i != cont_octet_count && from != from_end) {
|
|
||||||
|
|
||||||
// Error checking on continuing characters
|
|
||||||
if (invalid_continuing_octet(*from)) {
|
|
||||||
from_next = from;
|
|
||||||
to_next = to;
|
|
||||||
return std::codecvt_base::error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ucs_result *= (1 << 6);
|
|
||||||
|
|
||||||
// each continuing character has an extra (10xxxxxx)b attached to
|
|
||||||
// it that must be removed.
|
|
||||||
ucs_result += (unsigned char)(*from++) - 0x80;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the buffer ends with an incomplete unicode character...
|
|
||||||
if (from == from_end && i != cont_octet_count) {
|
|
||||||
// rewind "from" to before the current character translation
|
|
||||||
from_next = from - (i+1);
|
|
||||||
to_next = to;
|
|
||||||
return std::codecvt_base::partial;
|
|
||||||
}
|
|
||||||
*to++ = ucs_result;
|
|
||||||
}
|
|
||||||
from_next = from;
|
|
||||||
to_next = to;
|
|
||||||
|
|
||||||
// Were we done converting or did we run out of destination space?
|
|
||||||
if(from == from_end) return std::codecvt_base::ok;
|
|
||||||
else return std::codecvt_base::partial;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::codecvt_base::result utf8_codecvt_facet::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
|
|
||||||
{
|
|
||||||
// RG - consider merging this table with the other one
|
|
||||||
const wchar_t octet1_modifier_table[] = {
|
|
||||||
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
|
|
||||||
};
|
|
||||||
|
|
||||||
wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
|
|
||||||
while (from != from_end && to != to_end) {
|
|
||||||
|
|
||||||
// Check for invalid UCS-4 character
|
|
||||||
if (*from > max_wchar) {
|
|
||||||
from_next = from;
|
|
||||||
to_next = to;
|
|
||||||
return std::codecvt_base::error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cont_octet_count = get_cont_octet_out_count(*from);
|
|
||||||
|
|
||||||
// RG - comment this formula better
|
|
||||||
int shift_exponent = (cont_octet_count) * 6;
|
|
||||||
|
|
||||||
// Process the first character
|
|
||||||
*to++ = octet1_modifier_table[cont_octet_count] +
|
|
||||||
(unsigned char)(*from / (1 << shift_exponent));
|
|
||||||
|
|
||||||
// Process the continuation characters
|
|
||||||
// Invariants: At the start of the loop:
|
|
||||||
// 1) 'i' continuing octets have been generated
|
|
||||||
// 2) '*to' points to the next location to place an octet
|
|
||||||
// 3) shift_exponent is 6 more than needed for the next octet
|
|
||||||
int i = 0;
|
|
||||||
while (i != cont_octet_count && to != to_end) {
|
|
||||||
shift_exponent -= 6;
|
|
||||||
*to++ = 0x80 + ((*from / (1 << shift_exponent)) % (1 << 6));
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// If we filled up the out buffer before encoding the character
|
|
||||||
if(to == to_end && i != cont_octet_count) {
|
|
||||||
from_next = from;
|
|
||||||
to_next = to - (i+1);
|
|
||||||
return std::codecvt_base::partial;
|
|
||||||
}
|
|
||||||
*from++;
|
|
||||||
}
|
|
||||||
from_next = from;
|
|
||||||
to_next = to;
|
|
||||||
// Were we done or did we run out of destination space
|
|
||||||
if(from == from_end) return std::codecvt_base::ok;
|
|
||||||
else return std::codecvt_base::partial;
|
|
||||||
}
|
|
||||||
|
|
||||||
// How many char objects can I process to get <= max_limit
|
|
||||||
// wchar_t objects?
|
|
||||||
int utf8_codecvt_facet::do_length(
|
|
||||||
BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
|
|
||||||
const char * from,
|
|
||||||
const char * from_end,
|
|
||||||
std::size_t max_limit
|
|
||||||
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
|
|
||||||
) const throw()
|
|
||||||
#else
|
|
||||||
) const
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// RG - this code is confusing! I need a better way to express it.
|
|
||||||
// and test cases.
|
|
||||||
|
|
||||||
// Invariants:
|
|
||||||
// 1) last_octet_count has the size of the last measured character
|
|
||||||
// 2) char_count holds the number of characters shown to fit
|
|
||||||
// within the bounds so far (no greater than max_limit)
|
|
||||||
// 3) from_next points to the octet 'last_octet_count' before the
|
|
||||||
// last measured character.
|
|
||||||
int last_octet_count=0;
|
|
||||||
std::size_t char_count = 0;
|
|
||||||
const char* from_next = from;
|
|
||||||
// Use "<" because the buffer may represent incomplete characters
|
|
||||||
while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
|
|
||||||
from_next += last_octet_count;
|
|
||||||
last_octet_count = (get_octet_count(*from_next));
|
|
||||||
++char_count;
|
|
||||||
}
|
|
||||||
return from_next-from_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int utf8_codecvt_facet::get_octet_count(
|
|
||||||
unsigned char lead_octet
|
|
||||||
){
|
|
||||||
// if the 0-bit (MSB) is 0, then 1 character
|
|
||||||
if (lead_octet <= 0x7f) return 1;
|
|
||||||
|
|
||||||
// Otherwise the count number of consecutive 1 bits starting at MSB
|
|
||||||
// assert(0xc0 <= lead_octet && lead_octet <= 0xfd);
|
|
||||||
|
|
||||||
if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2;
|
|
||||||
else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3;
|
|
||||||
else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4;
|
|
||||||
else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5;
|
|
||||||
else return 6;
|
|
||||||
}
|
|
||||||
BOOST_UTF8_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
template<std::size_t s>
|
|
||||||
int get_cont_octet_out_count_impl(wchar_t word){
|
|
||||||
if (word < 0x80) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (word < 0x800) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note the following code will generate on some platforms where
|
|
||||||
// wchar_t is defined as UCS2. The warnings are superfluous as
|
|
||||||
// the specialization is never instantitiated with such compilers.
|
|
||||||
template<>
|
|
||||||
int get_cont_octet_out_count_impl<4>(wchar_t word){
|
|
||||||
if (word < 0x80) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (word < 0x800) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (word < 0x10000) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if (word < 0x200000) {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
if (word < 0x4000000) {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace anonymous
|
|
||||||
|
|
||||||
BOOST_UTF8_BEGIN_NAMESPACE
|
|
||||||
// How many "continuing octets" will be needed for this word
|
|
||||||
// == total octets - 1.
|
|
||||||
int utf8_codecvt_facet::get_cont_octet_out_count(
|
|
||||||
wchar_t word
|
|
||||||
) const {
|
|
||||||
return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
|
|
||||||
}
|
|
||||||
BOOST_UTF8_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
Reference in New Issue
Block a user