|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r68483 - in sandbox/coerce: . boost boost/coerce libs libs/coerce libs/coerce/example libs/coerce/test
From: vexocide_at_[hidden]
Date: 2011-01-27 14:23:40
Author: vexocide
Date: 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
New Revision: 68483
URL: http://svn.boost.org/trac/boost/changeset/68483
Log:
Initial commit of boost::coerce
Added:
sandbox/coerce/Jamroot (contents, props changed)
sandbox/coerce/LICENSE_1_0.txt (contents, props changed)
sandbox/coerce/boost/
sandbox/coerce/boost/coerce/
sandbox/coerce/boost/coerce.hpp (contents, props changed)
sandbox/coerce/boost/coerce/container.hpp (contents, props changed)
sandbox/coerce/boost/coerce/iterable.hpp (contents, props changed)
sandbox/coerce/boost/coerce/reserve.hpp (contents, props changed)
sandbox/coerce/boost/coerce/spirit.hpp (contents, props changed)
sandbox/coerce/boost/coerce/tag.hpp (contents, props changed)
sandbox/coerce/libs/
sandbox/coerce/libs/coerce/
sandbox/coerce/libs/coerce/example/
sandbox/coerce/libs/coerce/example/Jamfile.v2 (contents, props changed)
sandbox/coerce/libs/coerce/example/coerce.cpp (contents, props changed)
sandbox/coerce/libs/coerce/example/optional.cpp (contents, props changed)
sandbox/coerce/libs/coerce/example/tag.cpp (contents, props changed)
sandbox/coerce/libs/coerce/test/
sandbox/coerce/libs/coerce/test/Jamfile.v2 (contents, props changed)
sandbox/coerce/libs/coerce/test/iterable.cpp (contents, props changed)
sandbox/coerce/libs/coerce/test/reserve.cpp (contents, props changed)
Added: sandbox/coerce/Jamroot
==============================================================================
--- (empty file)
+++ sandbox/coerce/Jamroot 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,14 @@
+# Copyright Jeroen Habraken 2010.
+#
+# 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)
+
+import os ;
+use-project /boost :
+ [ os.environ BOOST_ROOT ] ;
+
+build-project libs/coerce/example ;
+
+using testing ;
+build-project libs/coerce/test ;
Added: sandbox/coerce/LICENSE_1_0.txt
==============================================================================
--- (empty file)
+++ sandbox/coerce/LICENSE_1_0.txt 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
Added: sandbox/coerce/boost/coerce.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,180 @@
+// 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_COERCE_HPP
+#define BOOST_COERCE_HPP
+
+#include <boost/coerce/container.hpp>
+#include <boost/coerce/iterable.hpp>
+#include <boost/coerce/reserve.hpp>
+#include <boost/coerce/spirit.hpp>
+#include <boost/coerce/tag.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/home/karma/auto.hpp>
+#include <boost/spirit/home/karma/char.hpp>
+#include <boost/spirit/home/karma/numeric.hpp>
+#include <boost/spirit/home/karma/operator/optional.hpp>
+#include <boost/spirit/home/qi/auto.hpp>
+#include <boost/spirit/home/qi/char.hpp>
+#include <boost/spirit/home/qi/numeric.hpp>
+#include <boost/spirit/home/qi/operator/optional.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/include/version.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <typeinfo> // for std::bad_cast
+
+namespace boost {
+
+ namespace coerce {
+
+ class bad_cast
+ : public std::bad_cast { };
+
+ namespace detail {
+
+ template <typename Target, typename Source, typename Tag>
+ struct as {
+ static inline bool
+ call(Target & target, Source const & source) {
+ return do_call(
+ target,
+ source,
+ traits::is_iterable<Source>(),
+ traits::is_container<Target>());
+ }
+
+ private:
+ static inline bool
+ do_call(
+ Target & target,
+ Source const & source,
+ mpl::true_ const,
+ bool const
+ ) {
+ typedef traits::iterable<Source> iterable_type;
+ typedef typename iterable_type::const_iterator iterator_type;
+
+ iterable_type iterable(source);
+
+ if (iterable.size() < 1)
+ return false;
+
+ call_reserve(target, iterable.size());
+
+ iterator_type begin = iterable.begin(), iterator = begin;
+ iterator_type end = iterable.end();
+
+ bool result = spirit::qi::parse(
+ iterator, end, wrap<Tag>::call(target));
+
+ if (!result || !((begin < iterator && iterator < end && *iterator == 0) || iterator == end))
+ return false;
+
+ return true;
+ }
+
+ static inline bool
+ do_call(
+ Target & target,
+ Source const & source,
+ mpl::false_ const,
+ mpl::true_ const
+ ) {
+ call_reserve(
+ target,
+ traits::reserve_size<Source, Tag>::call(source));
+
+ bool result = spirit::karma::generate(
+ std::back_inserter(target),
+#if SPIRIT_VERSION <= 0x2030
+ spirit::karma::auto_,
+#endif
+ wrap<Tag>::call(source));
+
+ return result;
+ }
+
+ static inline void
+ do_call(
+ Target & target,
+ Source const & source,
+ mpl::false_ const,
+ mpl::false_ const
+ ) {
+ // TODO, implement a lexical_cast fallback
+
+ BOOST_STATIC_ASSERT(sizeof(Target) == 0);
+ }
+ };
+
+ } // namespace detail
+
+ namespace traits {
+
+ template <typename Target, typename Source, typename Tag, typename Enable = void>
+ struct as
+ : coerce::detail::as<Target, Source, Tag> { };
+
+ } // namespace traits
+
+ template <typename Target, typename Source, typename Tag>
+ inline Target
+ as(Source const & source, Tag const &) {
+ Target target;
+
+ bool result = traits::as<
+ Target, Source, Tag
+ >::call(target, source);
+
+ if (!result)
+ throw coerce::bad_cast();
+
+ return target;
+ }
+
+ template <typename Target, typename Source>
+ inline Target
+ as(Source const & source) {
+ return as<Target, Source>(source, spirit::unused);
+ }
+
+ template <typename Target, typename Source, typename Tag>
+ inline typename disable_if<
+ is_same<Target, Tag>, Target>::type
+ as_default(
+ Source const & source,
+ Tag const &,
+ Target const & default_value = Target()
+ ) {
+ Target target;
+
+ bool result = traits::as<
+ Target, Source, Tag
+ >::call(target, source);
+
+ if (!result)
+ return default_value;
+
+ return target;
+ }
+
+ template <typename Target, typename Source>
+ inline Target
+ as_default(
+ Source const & source,
+ Target const & default_value = Target()
+ ) {
+ return as_default<Target, Source>(
+ source, spirit::unused, default_value);
+ }
+
+ } // namespace coerce
+
+} // namespace boost
+
+#endif // BOOST_COERCE_HPP
Added: sandbox/coerce/boost/coerce/container.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/container.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,51 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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_COERCE_CONTAINER_HPP
+#define BOOST_COERCE_CONTAINER_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost {
+
+ namespace coerce {
+
+ namespace traits {
+
+ namespace detail {
+
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
+
+ } // namespace detail
+
+ template <typename Type>
+ struct is_container_impl
+ : mpl::bool_<
+ detail::has_value_type<Type>::value &&
+ detail::has_iterator<Type>::value &&
+ detail::has_size_type<Type>::value &&
+ detail::has_reference<Type>::value> { };
+
+ template <typename Type, typename Enable = void>
+ struct is_container
+ : is_container_impl<
+ typename remove_const<
+ typename remove_reference<Type>::type
+ >::type> { };
+
+ } // namespace traits
+
+ } // namespace coerce
+
+} // namespace boost
+
+#endif // BOOST_COERCE_CONTAINER_HPP
Added: sandbox/coerce/boost/coerce/iterable.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/iterable.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,272 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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_COERCE_ITERABLE_HPP
+#define BOOST_COERCE_ITERABLE_HPP
+
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/optional.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <cstddef>
+#include <cstring>
+#include <cwchar>
+#include <string>
+
+namespace boost {
+
+ namespace coerce {
+
+ namespace traits {
+
+ struct not_iterable { };
+
+ template <typename Type>
+ struct iterable_impl
+ : mpl::identity<not_iterable> { };
+
+ template <>
+ struct iterable_impl<char const *> {
+ typedef char const * type;
+
+ typedef char * iterator;
+ typedef char const * const_iterator;
+
+ typedef std::size_t size_type;
+
+ iterable_impl(type const & value)
+ : value_(value) { }
+
+ inline const_iterator
+ begin() {
+ return value_;
+ }
+
+ inline const_iterator
+ end() {
+ return value_ + size();
+ }
+
+ inline size_type
+ size() {
+ if (!size_)
+ size_ = strlen(value_);
+
+ return size_.get();
+ }
+
+ private:
+ type const value_;
+
+ optional<size_type> mutable size_;
+ };
+
+ template <>
+ struct iterable_impl<char *>
+ : iterable_impl<char const *> {
+ typedef char * type;
+
+ iterable_impl(type const & value)
+ : iterable_impl<char const *>(value) { }
+ };
+
+ template <>
+ struct iterable_impl<wchar_t const *> {
+ typedef wchar_t const * type;
+
+ typedef wchar_t * iterator;
+ typedef wchar_t const * const_iterator;
+
+ typedef std::size_t size_type;
+
+ iterable_impl(type const & value)
+ : value_(value) { }
+
+ inline const_iterator
+ begin() {
+ return value_;
+ }
+
+ inline const_iterator
+ end() {
+ return value_ + size();
+ }
+
+ inline size_type
+ size() {
+ if (!size_)
+ size_ = wcslen(value_);
+
+ return size_.get();
+ }
+
+ private:
+ type const value_;
+
+ optional<size_type> mutable size_;
+ };
+
+ template <>
+ struct iterable_impl<wchar_t *>
+ : iterable_impl<wchar_t const *> {
+ typedef wchar_t * type;
+
+ iterable_impl(type const & value)
+ : iterable_impl<wchar_t const *>(value) { }
+ };
+
+ template <typename CharT, std::size_t N>
+ struct iterable_impl_extent {
+ typedef CharT type[N];
+
+ typedef CharT * iterator;
+ typedef CharT const * const_iterator;
+
+ typedef std::size_t size_type;
+
+ iterable_impl_extent(CharT const (& value)[N])
+ : value_(value) { }
+
+ inline const_iterator
+ begin() {
+ return &value_[0];
+ }
+
+ inline const_iterator
+ end() {
+ return &value_[0] + size();
+ }
+
+ inline size_type
+ size() {
+ return value_[N - 1] == 0 ? N - 1 : N;
+ }
+
+ private:
+ CharT const (& value_)[N];
+ };
+
+ template <std::size_t N>
+ struct iterable_impl<char [N]>
+ : iterable_impl_extent<char, N> {
+ iterable_impl(char const (& value)[N])
+ : iterable_impl_extent<char, N>(value) { }
+ };
+
+ template <std::size_t N>
+ struct iterable_impl<wchar_t [N]>
+ : iterable_impl_extent<wchar_t, N> {
+ iterable_impl(wchar_t const (& value)[N])
+ : iterable_impl_extent<wchar_t, N>(value) { }
+ };
+
+ template <typename CharT, typename Traits, typename Allocator>
+ struct iterable_impl<std::basic_string<CharT, Traits, Allocator> > {
+ typedef std::basic_string<CharT, Traits, Allocator> type;
+
+ typedef typename type::iterator iterator;
+ typedef typename type::const_iterator const_iterator;
+
+ typedef typename type::size_type size_type;
+
+ iterable_impl(type const & value)
+ : value_(value) { }
+
+ inline const_iterator
+ begin() {
+ return value_.begin();
+ }
+
+ inline const_iterator
+ end() {
+ return value_.end();
+ }
+
+ inline size_type
+ size() {
+ return value_.size();
+ }
+
+ private:
+ type const & value_;
+ };
+
+#ifdef BOOST_COERCE_ITERABLE_CHARACTER
+
+ template <typename CharT>
+ struct iterable_impl_char {
+ typedef CharT type;
+
+ typedef CharT * iterator;
+ typedef CharT const * const_iterator;
+
+ typedef std::size_t size_type;
+
+ iterable_impl_char(CharT const & value)
+ : value_(value) { }
+
+ inline const_iterator
+ begin() {
+ return &value_;
+ }
+
+ inline const_iterator
+ end() {
+ return &value_ + size();
+ }
+
+ inline size_type
+ size() {
+ return value_ == 0 ? 0 : 1;
+ }
+
+ private:
+ CharT const & value_;
+ };
+
+ template <>
+ struct iterable_impl<char>
+ : iterable_impl_char<char> {
+ iterable_impl(char const & value)
+ : iterable_impl_char<char>(value) { }
+ };
+
+ template <>
+ struct iterable_impl<wchar_t>
+ : iterable_impl_char<wchar_t> {
+ iterable_impl(wchar_t const & value)
+ : iterable_impl_char<wchar_t>(value) { }
+ };
+
+#endif // BOOST_COERCE_ITERABLE_CHARACTER
+
+ template <typename Type, typename Enable = void>
+ struct iterable
+ : iterable_impl<
+ typename remove_const<
+ typename remove_reference<Type>::type
+ >::type> {
+ iterable(typename iterable<Type>::type const & value)
+ : iterable_impl<typename iterable<Type>::type>(value) { }
+ };
+
+ template <typename Type>
+ struct is_iterable
+ : mpl::not_<is_same<
+ typename iterable<Type>::type,
+ not_iterable
+ > > { };
+
+ } // namespace traits
+
+ } // namespace coerce
+
+} // namespace boost
+
+#endif // BOOST_COERCE_ITERABLE_HPP
Added: sandbox/coerce/boost/coerce/reserve.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/reserve.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,220 @@
+// Copyright Adam Merz 2010.
+// Copyright Jeroen Habraken 2010.
+//
+// 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_COERCE_RESERVE_HPP
+#define BOOST_COERCE_RESERVE_HPP
+
+#include <boost/coerce/tag.hpp>
+
+#include <boost/config.hpp>
+#include <boost/limits.hpp>
+#include <boost/optional.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <cstddef>
+
+#ifndef BOOST_COERCE_UNSPECIALIZED_RESERVE
+#define BOOST_COERCE_UNSPECIALIZED_RESERVE 16
+#endif // BOOST_COERCE_UNSPECIALIZED_RESERVE
+
+namespace boost {
+
+ namespace coerce {
+
+ namespace traits {
+
+ template <typename Type, typename Tag>
+ struct reserve_size_impl {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ BOOST_COERCE_UNSPECIALIZED_RESERVE);
+ };
+
+ template <typename Tag>
+ struct reserve_size_impl<char, Tag> {
+ BOOST_STATIC_CONSTANT(std::size_t, value = 1);
+ };
+
+ template <typename Tag>
+ struct reserve_size_impl<wchar_t, Tag> {
+ BOOST_STATIC_CONSTANT(std::size_t, value = 1);
+ };
+
+ template <typename Type, typename Tag>
+ struct reserve_size_impl_integral {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ std::numeric_limits<Type>::is_signed +
+ 1 +
+ std::numeric_limits<Type>::digits10);
+ };
+
+ template <typename Type>
+ struct reserve_size_impl_integral<Type, tag::bin_type> {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ 1 +
+ std::numeric_limits<Type>::digits);
+ };
+
+ template <typename Type>
+ struct reserve_size_impl_integral<Type, tag::oct_type> {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ 1 +
+ (std::numeric_limits<Type>::digits / 3));
+ };
+
+ template <typename Type>
+ struct reserve_size_impl_integral<Type, tag::hex_type> {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ 1 +
+ (std::numeric_limits<Type>::digits / 4));
+ };
+
+ template <typename Tag>
+ struct reserve_size_impl<int, Tag>
+ : reserve_size_impl_integral<int, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<short, Tag>
+ : reserve_size_impl_integral<short, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<long, Tag>
+ : reserve_size_impl_integral<long, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<unsigned int, Tag>
+ : reserve_size_impl_integral<unsigned int, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<unsigned short, Tag>
+ : reserve_size_impl_integral<unsigned short, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<unsigned long, Tag>
+ : reserve_size_impl_integral<unsigned long, Tag> { };
+
+#ifdef BOOST_HAS_LONG_LONG
+
+ template <typename Tag>
+ struct reserve_size_impl<boost::long_long_type, Tag>
+ : reserve_size_impl_integral<boost::long_long_type, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<boost::ulong_long_type, Tag>
+ : reserve_size_impl_integral<boost::ulong_long_type, Tag> { };
+
+#endif // BOOST_HAS_LONG_LONG
+
+ template <typename Type, typename Tag>
+ struct reserve_size_impl_floating_point {
+ BOOST_STATIC_CONSTANT(std::size_t, value =
+ std::numeric_limits<Type>::is_signed +
+ 8 +
+ std::numeric_limits<Type>::digits10);
+ };
+
+ template <typename Tag>
+ struct reserve_size_impl<float, Tag>
+ : reserve_size_impl_floating_point<float, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<double, Tag>
+ : reserve_size_impl_floating_point<double, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<long double, Tag>
+ : reserve_size_impl_floating_point<long double, Tag> { };
+
+ template <typename Tag>
+ struct reserve_size_impl<bool, Tag> {
+ BOOST_STATIC_CONSTANT(std::size_t, value = 5);
+ };
+
+ template <typename Type, typename Tag>
+ struct reserve_size_impl<boost::optional<Type>, Tag>
+ : reserve_size_impl<Type, Tag> { };
+
+ template <typename Type, typename Tag, typename Enable = void>
+ struct reserve_size {
+ typedef std::size_t type;
+
+ static inline type
+ call(typename remove_reference<Type>::type const &) {
+ return reserve_size_impl<
+ typename remove_const<
+ typename remove_reference<Type>::type
+ >::type, Tag>::value;
+ }
+ };
+
+ } // namespace traits
+
+ namespace detail {
+
+ template <typename Sequence>
+ class has_reserve {
+ template <typename U, void (U::*)(typename U::size_type) = &U::reserve>
+ struct impl { };
+
+ template <typename U>
+ static type_traits::yes_type test(U*, impl<U>* = 0);
+
+ template <typename U>
+ static type_traits::no_type test(...);
+
+ public:
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof(test<Sequence>(0)) == sizeof(type_traits::yes_type));
+ typedef mpl::bool_<value> type;
+ };
+
+ template <typename Sequence>
+ inline void
+ call_reserve_impl(
+ Sequence & sequence,
+ typename Sequence::size_type const size,
+ mpl::true_ const
+ ) {
+ sequence.reserve(size);
+ }
+
+ template <typename Sequence>
+ inline void
+ call_reserve_impl(
+ Sequence const &,
+ typename Sequence::size_type const,
+ mpl::false_ const
+ ) {
+ // Missing .reserve()
+ }
+
+ template <typename Sequence>
+ inline void
+ call_reserve(
+ Sequence & sequence,
+ typename Sequence::size_type const size
+ ) {
+ call_reserve_impl(
+ sequence, size, typename has_reserve<Sequence>::type());
+ }
+
+ template <typename Sequence>
+ inline void
+ call_reserve(
+ Sequence const &,
+ std::size_t const
+ ) {
+ // Missing size_type
+ }
+
+ } // namespace detail
+
+ } // namespace coerce
+
+} // namespace boost
+
+#endif // BOOST_COERCE_RESERVE_HPP
Added: sandbox/coerce/boost/coerce/spirit.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/spirit.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,226 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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_COERCE_SPIRIT_HPP
+#define BOOST_COERCE_SPIRIT_HPP
+
+#include <boost/limits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/spirit/home/karma/auto.hpp>
+#include <boost/spirit/home/karma/numeric/real.hpp>
+#include <boost/spirit/home/karma/numeric/real_policies.hpp>
+#include <boost/spirit/home/qi/auto.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/include/version.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost {
+
+ namespace coerce {
+
+ namespace detail {
+
+ template <typename Type, typename Tag>
+ struct wrapped {
+ wrapped(Type & value)
+ : value_(value) { }
+
+ inline Type const &
+ get_value() const {
+ return value_;
+ }
+
+ inline void
+ set_value(Type const & value) {
+ value_ = value;
+ }
+
+ private:
+ Type & value_;
+ };
+
+ template <typename Tag>
+ struct wrap {
+ template <typename Type>
+ static inline wrapped<
+ typename remove_reference<Type>::type,
+ Tag
+ >
+ call(Type & value) {
+ return value;
+ }
+ };
+
+ template <>
+ struct wrap<spirit::unused_type> {
+ template <typename Type>
+ struct result {
+ typedef typename mpl::if_<
+ is_floating_point<Type>,
+ wrapped<
+ typename remove_reference<Type>::type,
+ spirit::unused_type
+ >,
+ Type &
+ >::type type;
+ };
+
+ template <typename Type>
+ static inline typename result<Type>::type
+ call(Type & value) {
+ return value;
+ }
+ };
+
+ template <typename Target, typename Tag>
+ struct create_parser {
+ typedef typename Tag::template parser<Target>::type type;
+
+ static inline type const
+ call() {
+ return Tag::template parser<Target>::call();
+ }
+ };
+
+ template <typename Target>
+ struct create_parser<Target, spirit::unused_type>
+ : spirit::traits::create_parser<Target> { };
+
+ template <typename Source, typename Tag>
+ struct create_generator {
+ typedef typename Tag::template generator<Source>::type type;
+
+ static inline type const
+ call() {
+ return Tag::template generator<Source>::call();
+ }
+ };
+
+ template <typename Source>
+ struct create_generator<Source, spirit::unused_type>
+ : spirit::traits::create_generator<Source> { };
+
+ template <typename Source>
+ struct real_policies
+ : spirit::karma::real_policies<Source> {
+ static inline unsigned
+ precision(Source const &) {
+ return std::numeric_limits<Source>::digits10 + 1;
+ }
+ };
+
+ template <typename Source>
+ struct create_generator_floating_point {
+ typedef spirit::karma::real_generator<
+ Source,
+ real_policies<typename remove_const<Source>::type>
+ > type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+
+ template <>
+ struct create_generator<float, spirit::unused_type>
+ : create_generator_floating_point<float> { };
+
+ template <>
+ struct create_generator<double, spirit::unused_type>
+ : create_generator_floating_point<double> { };
+
+ template <>
+ struct create_generator<long double, spirit::unused_type>
+ : create_generator_floating_point<long double> { };
+
+ } // namespace detail
+
+ } // namespace coerce
+
+ namespace spirit {
+
+ namespace traits {
+
+ template <typename Target, typename Tag>
+ struct create_parser<coerce::detail::wrapped<Target, Tag> >
+ : coerce::detail::create_parser<
+ // NOTE, reference already remove in coerce::detail::wrap
+ typename remove_const<Target>::type,
+ Tag
+ > { };
+
+ template <typename Target, typename Tag>
+ struct assign_to_attribute_from_value<
+ coerce::detail::wrapped<Target, Tag>,
+ typename remove_const<Target>::type
+ > {
+ static inline void
+ call(
+ Target const & value,
+ coerce::detail::wrapped<Target, Tag> & attribute
+ ) {
+ attribute.set_value(value);
+ }
+ };
+
+ template <typename Target, typename Tag, typename Attrib>
+ struct assign_to_attribute_from_value<
+ coerce::detail::wrapped<Target, Tag>,
+ Attrib
+ > {
+ BOOST_STATIC_ASSERT(sizeof(Target) == 0);
+ };
+
+ template <typename Source, typename Tag>
+ struct create_generator<coerce::detail::wrapped<Source, Tag> >
+ : coerce::detail::create_generator<
+ // NOTE, reference already remove in coerce::detail::wrap
+ typename remove_const<Source>::type,
+ Tag
+ > { };
+
+ template <typename Source, typename Tag>
+ struct extract_from_attribute<
+#if SPIRIT_VERSION >= 2040
+ coerce::detail::wrapped<Source, Tag>,
+ typename remove_const<Source>::type
+#else
+ coerce::detail::wrapped<Source, Tag>
+#endif
+ > {
+ typedef Source type;
+
+ template <typename Context>
+ static inline type const &
+ call(
+ coerce::detail::wrapped<Source, Tag> const & attribute,
+ Context &
+ ) {
+ return attribute.get_value();
+ }
+ };
+
+#if SPIRIT_VERSION >= 2040
+ template <typename Source, typename Tag, typename Attrib>
+ struct extract_from_attribute<
+ coerce::detail::wrapped<Source, Tag>,
+ Attrib
+ > {
+ BOOST_STATIC_ASSERT(sizeof(Source) == 0);
+ };
+#endif
+
+ } // namespace traits
+
+ } // namespace spirit
+
+} // namespace boost
+
+#endif // BOOST_COERCE_SPIRIT_HPP
Added: sandbox/coerce/boost/coerce/tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/tag.hpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,150 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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_COERCE_TAG_HPP
+#define BOOST_COERCE_TAG_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/proto/deep_copy.hpp>
+#include <boost/spirit/home/karma/auto.hpp>
+#include <boost/spirit/home/karma/numeric.hpp>
+#include <boost/spirit/home/qi/auto.hpp>
+#include <boost/spirit/home/qi/directive/no_case.hpp>
+#include <boost/spirit/home/qi/numeric.hpp>
+#include <boost/spirit/home/qi/operator/sequence.hpp>
+#include <boost/spirit/home/qi/operator/optional.hpp>
+#include <boost/spirit/home/qi/string/lit.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+
+namespace boost {
+
+ namespace coerce {
+
+ namespace detail {
+
+ // TODO, numeric_parser and numeric_generator: http://codepad.org/qbneDiqx
+
+ } // namespace detail
+
+ namespace tag {
+
+ struct bin_type {
+ template <typename Target>
+ struct parser {
+ BOOST_STATIC_ASSERT(is_integral<Target>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Target>,
+ spirit::qi::int_parser<Target, 2>,
+ spirit::qi::uint_parser<Target, 2>
+ >::type type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+
+ template <typename Source>
+ struct generator {
+ BOOST_STATIC_ASSERT(is_integral<Source>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Source>,
+ spirit::karma::int_generator<Source, 2>,
+ spirit::karma::uint_generator<Source, 2>
+ >::type type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+ } const bin = bin_type();
+
+ struct oct_type {
+ template <typename Target>
+ struct parser {
+ BOOST_STATIC_ASSERT(is_integral<Target>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Target>,
+ spirit::qi::int_parser<Target, 8>,
+ spirit::qi::uint_parser<Target, 8>
+ >::type type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+
+ template <typename Source>
+ struct generator {
+ BOOST_STATIC_ASSERT(is_integral<Source>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Source>,
+ spirit::karma::int_generator<Source, 8>,
+ spirit::karma::uint_generator<Source, 8>
+ >::type type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+ } const oct = oct_type();
+
+ struct hex_type {
+ template <typename Target>
+ struct parser {
+ BOOST_STATIC_ASSERT(is_integral<Target>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Target>,
+ spirit::qi::int_parser<Target, 16>,
+ spirit::qi::uint_parser<Target, 16>
+ >::type parser_type;
+
+ typedef typename proto::result_of::deep_copy<
+ BOOST_TYPEOF((-spirit::standard::no_case["0x"] >> parser_type()))
+ >::type type;
+
+ static inline type const
+ call() {
+ return proto::deep_copy(
+ -spirit::standard::no_case["0x"] >> parser_type());
+ }
+ };
+
+ template <typename Source>
+ struct generator {
+ BOOST_STATIC_ASSERT(is_integral<Source>::value);
+
+ typedef typename mpl::if_<
+ is_signed<Source>,
+ spirit::karma::int_generator<Source, 16>,
+ spirit::karma::uint_generator<Source, 16>
+ >::type type;
+
+ static inline type const
+ call() {
+ return type();
+ }
+ };
+ } const hex = hex_type();
+
+ } // namespace tag
+
+ } // namespace coerce
+
+} // namespace boost
+
+#endif // BOOST_COERCE_TAG_HPP
Added: sandbox/coerce/libs/coerce/example/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/example/Jamfile.v2 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,21 @@
+# Copyright Jeroen Habraken 2010.
+#
+# 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)
+
+project coerce_example :
+ requirements
+ <dependency>/boost//headers
+ <include>../../../
+ <optimization>speed
+ ;
+
+exe coerce :
+ coerce.cpp ;
+
+exe optional :
+ optional.cpp ;
+
+exe tag :
+ tag.cpp ;
Added: sandbox/coerce/libs/coerce/example/coerce.cpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/example/coerce.cpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,25 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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)
+
+#include <boost/coerce.hpp>
+
+#include <iostream>
+#include <ostream>
+#include <string>
+
+int
+main() {
+ using namespace boost;
+
+ // A coerce from string to integer ..
+ std::cout << coerce::as<int>("23") << std::endl;
+
+ // .. and vice-versa
+ std::cout << coerce::as<std::string>(23) << std::endl;
+
+ // A no-throw coerce from string to integer with default value
+ std::cout << coerce::as_default<int>("XXX", 23) << std::endl;
+}
Added: sandbox/coerce/libs/coerce/example/optional.cpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/example/optional.cpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,35 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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)
+
+#include <boost/coerce.hpp>
+#include <boost/optional.hpp>
+
+#include <iostream>
+#include <ostream>
+
+namespace std {
+
+ template <typename T>
+ std::ostream &
+ operator<<(std::ostream & out, boost::optional<T> const & optional) {
+ if (optional)
+ return out << *optional;
+
+ return out;
+ }
+
+} // namespace std
+
+int
+main() {
+ using namespace boost;
+
+ // A no-throw coerce returning an optional<int>(23)
+ std::cout << coerce::as_default<optional<int> >("23") << std::endl;
+
+ // A no-throw coerce returning an empty, default constructed optional<int>
+ std::cout << coerce::as_default<optional<int> >("XXX") << std::endl;
+}
Added: sandbox/coerce/libs/coerce/example/tag.cpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/example/tag.cpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,22 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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)
+
+#include <boost/coerce.hpp>
+
+#include <iostream>
+#include <ostream>
+#include <string>
+
+int
+main() {
+ using namespace boost;
+
+ // A coerce from a binary string representation to integer ..
+ std::cout << coerce::as<int>("10111", coerce::tag::bin) << std::endl;
+
+ // .. and vice-versa
+ std::cout << coerce::as<std::string>(23, coerce::tag::bin) << std::endl;
+}
Added: sandbox/coerce/libs/coerce/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/test/Jamfile.v2 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,17 @@
+# Copyright Jeroen Habraken 2010.
+#
+# 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)
+
+project coerce_test :
+ requirements
+ <include>../../../
+ <source>/boost//unit_test_framework
+ ;
+
+unit-test iterable :
+ iterable.cpp ;
+
+unit-test reserve :
+ reserve.cpp ;
Added: sandbox/coerce/libs/coerce/test/iterable.cpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/test/iterable.cpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,92 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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)
+
+#define BOOST_TEST_MODULE iterable
+
+#include <boost/coerce.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+
+BOOST_TEST_DONT_PRINT_LOG_VALUE(std::string::const_iterator)
+
+BOOST_AUTO_TEST_CASE(iterable) {
+ using boost::coerce::traits::iterable;
+
+ char const * test_char_const_pointer = "test";
+ iterable<char const *> test_iterable_char_const_pointer(
+ test_char_const_pointer);
+ BOOST_CHECK_EQUAL(
+ test_iterable_char_const_pointer.begin(),
+ &test_char_const_pointer[0]);
+ BOOST_CHECK_EQUAL(
+ test_iterable_char_const_pointer.end(),
+ &test_char_const_pointer[0] + 4);
+ BOOST_CHECK_EQUAL(test_iterable_char_const_pointer.size(), 4u);
+
+ wchar_t const * test_wchar_t_const_pointer = L"test";
+ iterable<wchar_t const *> test_iterable_wchar_t_const_pointer(
+ test_wchar_t_const_pointer);
+ BOOST_CHECK_EQUAL(
+ test_iterable_wchar_t_const_pointer.begin(),
+ &test_wchar_t_const_pointer[0]);
+ BOOST_CHECK_EQUAL(
+ test_iterable_wchar_t_const_pointer.end(),
+ &test_wchar_t_const_pointer[0] + 4);
+ BOOST_CHECK_EQUAL(test_iterable_wchar_t_const_pointer.size(), 4u);
+
+ char const test_char_const_extend[5] = "test";
+ iterable<char const *> test_iterable_char_const_extend(
+ test_char_const_extend);
+ BOOST_CHECK_EQUAL(
+ test_iterable_char_const_extend.begin(), &test_char_const_extend[0]);
+ BOOST_CHECK_EQUAL(
+ test_iterable_char_const_extend.end(), &test_char_const_extend[0] + 4);
+ BOOST_CHECK_EQUAL(test_iterable_char_const_extend.size(), 4u);
+
+ std::string const test_string_const("test");
+ iterable<std::string const> test_iterable_string_const(test_string_const);
+ BOOST_CHECK_EQUAL(
+ test_iterable_string_const.begin(), test_string_const.begin());
+ BOOST_CHECK_EQUAL(
+ test_iterable_string_const.end(), test_string_const.end());
+ BOOST_CHECK_EQUAL(
+ test_iterable_string_const.size(), 4u);
+}
+
+BOOST_AUTO_TEST_CASE(is_iterable) {
+ using boost::coerce::traits::is_iterable;
+
+ BOOST_CHECK(!is_iterable<bool>::type());
+
+ BOOST_CHECK(is_iterable<char *>::type());
+ BOOST_CHECK(is_iterable<char const *>::type());
+ BOOST_CHECK(is_iterable<char * const>::type());
+ BOOST_CHECK(is_iterable<char const * const>::type());
+ BOOST_CHECK(is_iterable<char [1]>::type());
+ BOOST_CHECK(is_iterable<char const [1]>::type());
+ BOOST_CHECK(is_iterable<char (&)[1]>::type());
+ BOOST_CHECK(is_iterable<char const (&)[1]>::type());
+
+ BOOST_CHECK(is_iterable<wchar_t *>::type());
+ BOOST_CHECK(is_iterable<wchar_t const *>::type());
+ BOOST_CHECK(is_iterable<wchar_t * const>::type());
+ BOOST_CHECK(is_iterable<wchar_t const * const>::type());
+ BOOST_CHECK(is_iterable<wchar_t [1]>::type());
+ BOOST_CHECK(is_iterable<wchar_t const [1]>::type());
+ BOOST_CHECK(is_iterable<wchar_t (&)[1]>::type());
+ BOOST_CHECK(is_iterable<wchar_t const (&)[1]>::type());
+
+ BOOST_CHECK(is_iterable<std::string>::type());
+ BOOST_CHECK(is_iterable<std::string const>::type());
+ BOOST_CHECK(is_iterable<std::string &>::type());
+ BOOST_CHECK(is_iterable<std::string const &>::type());
+
+ BOOST_CHECK(is_iterable<std::wstring>::type());
+ BOOST_CHECK(is_iterable<std::wstring const>::type());
+ BOOST_CHECK(is_iterable<std::wstring &>::type());
+ BOOST_CHECK(is_iterable<std::wstring const &>::type());
+}
Added: sandbox/coerce/libs/coerce/test/reserve.cpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/libs/coerce/test/reserve.cpp 2011-01-27 14:23:37 EST (Thu, 27 Jan 2011)
@@ -0,0 +1,71 @@
+// Copyright Jeroen Habraken 2010.
+//
+// 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)
+
+#define BOOST_COERCE_UNSPECIALIZED_RESERVE 0
+#define BOOST_TEST_MODULE reserve
+
+#include <boost/coerce.hpp>
+#include <boost/optional.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+
+BOOST_AUTO_TEST_CASE(reserve_size) {
+ using namespace boost::coerce::tag;
+
+ using boost::coerce::traits::reserve_size;
+ using boost::spirit::unused_type;
+
+ BOOST_CHECK_GT((reserve_size<char, unused_type>::call('\0')), 0u);
+ BOOST_CHECK_GT((reserve_size<wchar_t, unused_type>::call(L'\0')), 0u);
+ short const test_short = 0;
+ BOOST_CHECK_GT((reserve_size<short, unused_type>::call(test_short)), 0u);
+ BOOST_CHECK_GT((reserve_size<int, unused_type>::call(0)), 0u);
+ BOOST_CHECK_GT((reserve_size<long, unused_type>::call(0l)), 0u);
+ unsigned short const test_unsigned_short = 0u;
+ BOOST_CHECK_GT((reserve_size<unsigned short, unused_type>::call(
+ test_unsigned_short)), 0u);
+ BOOST_CHECK_GT((reserve_size<unsigned int, unused_type>::call(0u)), 0u);
+ BOOST_CHECK_GT((reserve_size<unsigned long, unused_type>::call(0ul)), 0u);
+ BOOST_CHECK_GT((reserve_size<float, unused_type>::call(0.0f)), 0u);
+ BOOST_CHECK_GT((reserve_size<double, unused_type>::call(0.0)), 0u);
+ BOOST_CHECK_GT((reserve_size<long double, unused_type>::call(0.0l)), 0u);
+ BOOST_CHECK_GT((reserve_size<bool, unused_type>::call(false)), 0u);
+
+ BOOST_CHECK_GT((reserve_size<char const, unused_type>::call('\0')), 0u);
+ BOOST_CHECK_GT((reserve_size<char &, unused_type>::call('\0')), 0u);
+ BOOST_CHECK_GT((reserve_size<char const &, unused_type>::call('\0')), 0u);
+
+ BOOST_CHECK_GT((reserve_size<boost::optional<char>, unused_type>::call(
+ boost::optional<char>('\0'))), 0u);
+
+ BOOST_CHECK_GT((reserve_size<int, bin_type>::call(0)), 0u);
+ BOOST_CHECK_GT((reserve_size<int, oct_type>::call(0)), 0u);
+ BOOST_CHECK_GT((reserve_size<int, hex_type>::call(0)), 0u);
+}
+
+BOOST_AUTO_TEST_CASE(has_reserve) {
+ using boost::coerce::detail::has_reserve;
+
+ BOOST_CHECK(!has_reserve<bool>::type());
+
+ BOOST_CHECK(has_reserve<std::string>::type());
+ BOOST_CHECK(has_reserve<std::wstring>::type());
+
+ BOOST_CHECK(has_reserve<std::vector<char> >::type());
+ BOOST_CHECK(has_reserve<std::vector<wchar_t> >::type());
+}
+
+BOOST_AUTO_TEST_CASE(call_reserve) {
+ using boost::coerce::detail::call_reserve;
+
+ call_reserve('\0', 1u);
+
+ std::string test_string;
+ call_reserve(test_string, 1u);
+ BOOST_CHECK_EQUAL(test_string.capacity(), 1u);
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk