mirror of
https://github.com/boostorg/convert.git
synced 2026-01-30 07:42:47 +00:00
170 lines
5.0 KiB
C++
170 lines
5.0 KiB
C++
/// \file boost/convert.hpp
|
|
/// Public interface to the Boost.Convert framework.
|
|
//
|
|
// Boost.Convert library
|
|
// Copyright (c) 2009-2014 Vladimir Batov.
|
|
//
|
|
// Many thanks to
|
|
// Andrzej Krzemienski for helping great deal to partition responsibilities and to ultimately pave
|
|
// the way for the tr1::optional deployment;
|
|
// Edward Diener the Boost Review Manager for helping with the converters' design, his continuous
|
|
// involvement, technical and administrative help, guidance and advice;
|
|
// Kevlin Henney and Dave Abrahams for their ['lexical_cast]-related insights and explanations;
|
|
// Rob Stewart and Alex Hagen-Zanker for making sure the performance tests work as they should.
|
|
//
|
|
// Use, modification and distribution are subject to the Boost Software License,
|
|
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
|
|
|
|
#ifndef BOOST_CONVERT_API_HPP
|
|
#define BOOST_CONVERT_API_HPP
|
|
|
|
#include "./detail/safebool.hpp"
|
|
#include "./detail/workarounds.hpp"
|
|
#include "./detail/string.hpp"
|
|
#include <boost/throw_exception.hpp>
|
|
#include <stdexcept>
|
|
|
|
namespace boost
|
|
{
|
|
template<typename> struct convert;
|
|
}
|
|
|
|
template<typename TypeOut>
|
|
struct boost::convert
|
|
{
|
|
struct result;
|
|
template<typename, typename> struct algorithm_helper;
|
|
|
|
typedef boost::convert<TypeOut> this_type;
|
|
typedef typename convert_detail::corrected<TypeOut>::type out_type;
|
|
typedef typename boost::convert<out_type>::result result_type;
|
|
|
|
static out_type create_storage() { return out_type(); }
|
|
|
|
template<typename TypeIn, typename Converter>
|
|
static
|
|
result_type
|
|
from(TypeIn const& value_in, Converter const& converter) //C1.
|
|
{
|
|
result_type result (this_type::create_storage()); //C2
|
|
bool success = converter(value_in, result.value_); //C3
|
|
|
|
return success ? result : result(false);
|
|
}
|
|
|
|
template<typename TypeIn, typename Converter>
|
|
static
|
|
algorithm_helper<TypeIn, Converter>
|
|
from(Converter const& cnv)
|
|
{
|
|
return algorithm_helper<TypeIn, Converter>(cnv);
|
|
}
|
|
};
|
|
|
|
// Used temporarily. To be replaced with tr1::optional or improved boost::optional.
|
|
template<typename TypeOut>
|
|
struct boost::convert<TypeOut>::result
|
|
{
|
|
typedef result this_type;
|
|
typedef boost::safebool<result> safebool;
|
|
|
|
result (out_type const& v) : value_(v), good_(true) {}
|
|
|
|
bool operator! () const { return !good_; }
|
|
operator typename safebool::type () const { return safebool(!operator!()); }
|
|
// operator out_type const& () const { return this_type::value(); }
|
|
|
|
out_type const& value() const
|
|
{
|
|
if (!good_)
|
|
BOOST_THROW_EXCEPTION(std::invalid_argument("boost::convert failed"));
|
|
|
|
return value_;
|
|
}
|
|
|
|
template<typename FallbackType>
|
|
out_type value_or(FallbackType const& fallback) const
|
|
{
|
|
return good_ ? value_ : fallback;
|
|
}
|
|
|
|
private:
|
|
|
|
friend struct boost::convert<TypeOut>;
|
|
|
|
this_type& operator()(bool good) { return (good_ = good, *this); }
|
|
|
|
out_type value_;
|
|
bool good_;
|
|
};
|
|
|
|
template<typename TypeOut>
|
|
template<typename TypeIn, typename Converter>
|
|
struct boost::convert<TypeOut>::algorithm_helper
|
|
{
|
|
struct with_fallback;
|
|
|
|
typedef algorithm_helper this_type;
|
|
|
|
algorithm_helper(Converter const& cnv) : converter_(&cnv) {}
|
|
|
|
template<typename FallbackType>
|
|
with_fallback
|
|
value_or(FallbackType const&);
|
|
|
|
TypeOut operator()(TypeIn const& value_in)
|
|
{
|
|
out_type result = boost::convert<TypeOut>::create_storage();
|
|
bool good = (*converter_)(value_in, result);
|
|
|
|
if (!good)
|
|
BOOST_THROW_EXCEPTION(std::invalid_argument("boost::convert failed"));
|
|
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
|
|
Converter const* converter_;
|
|
};
|
|
|
|
template<typename TypeOut>
|
|
template<typename TypeIn, typename Converter>
|
|
struct boost::convert<TypeOut>::algorithm_helper<TypeIn, Converter>::with_fallback
|
|
:
|
|
public boost::convert<TypeOut>::template algorithm_helper<TypeIn, Converter>
|
|
{
|
|
typedef with_fallback this_type;
|
|
#if defined(_MSC_VER)
|
|
typedef typename boost::convert<TypeOut>::algorithm_helper<TypeIn, Converter> base_type;
|
|
#else
|
|
typedef boost::convert<TypeOut>::algorithm_helper<TypeIn, Converter> base_type;
|
|
#endif
|
|
with_fallback(base_type const& ah, TypeOut const& fallback)
|
|
:
|
|
base_type (ah),
|
|
fallback_ (fallback)
|
|
{}
|
|
|
|
TypeOut operator()(TypeIn const& value_in)
|
|
{
|
|
out_type result = boost::convert<TypeOut>::create_storage();
|
|
bool good = (*converter_)(value_in, result);
|
|
|
|
return good ? result : fallback_;
|
|
}
|
|
|
|
out_type fallback_;
|
|
};
|
|
|
|
template<typename TypeOut>
|
|
template<typename TypeIn, typename Converter>
|
|
template<typename FallbackType>
|
|
typename boost::convert<TypeOut>::template algorithm_helper<TypeIn, Converter>::with_fallback
|
|
boost::convert<TypeOut>::algorithm_helper<TypeIn, Converter>::value_or(FallbackType const& fallback)
|
|
{
|
|
return with_fallback(*this, fallback);
|
|
}
|
|
|
|
#endif // BOOST_CONVERT_API_HPP
|