$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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);
+}