we need an autodiff library at some point (or we need to roll our own but I do not think that makes sense). CppAD is well tested and header only and easy to include. It is also Liscene compatible with GPL v3.0. Here we bring it in as a dependency
173 lines
4.9 KiB
C++
173 lines
4.9 KiB
C++
# ifndef CPPAD_UTILITY_TO_STRING_HPP
|
|
# define CPPAD_UTILITY_TO_STRING_HPP
|
|
/* --------------------------------------------------------------------------
|
|
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell
|
|
|
|
CppAD is distributed under the terms of the
|
|
Eclipse Public License Version 2.0.
|
|
|
|
This Source Code may also be made available under the following
|
|
Secondary License when the conditions for such availability set forth
|
|
in the Eclipse Public License, Version 2.0 are satisfied:
|
|
GNU General Public License, Version 2.0 or later.
|
|
---------------------------------------------------------------------------- */
|
|
|
|
/*
|
|
$begin to_string$$
|
|
$spell
|
|
cppad.hpp
|
|
long long
|
|
std
|
|
const
|
|
ostringstream
|
|
$$
|
|
|
|
$section Convert Certain Types to a String$$
|
|
|
|
$head Syntax$$
|
|
$codei%# include <cppad/utility/to_string.hpp>
|
|
%$$
|
|
$icode%s% = to_string(%value%)%$$.
|
|
|
|
$head See Also$$
|
|
$cref base_to_string$$, $cref ad_to_string$$
|
|
|
|
$head Purpose$$
|
|
This routine is similar to the C++11 routine $code std::to_string$$
|
|
with the following differences:
|
|
$list number$$
|
|
It works with C++98.
|
|
$lnext
|
|
It has been extended to the fundamental floating point types.
|
|
$lnext
|
|
It has specifications for extending to an arbitrary type; see
|
|
$cref base_to_string$$.
|
|
$lnext
|
|
If $code <cppad/cppad.hpp>$$ is included,
|
|
and it has been extended to a $icode Base$$ type,
|
|
it automatically extends to the
|
|
$cref/AD types above Base/glossary/AD Type Above Base/$$.
|
|
$lnext
|
|
For integer types, conversion to a string is exact.
|
|
For floating point types, conversion to a string yields a value
|
|
that has relative error within machine epsilon.
|
|
$lend
|
|
|
|
$head value$$
|
|
|
|
$subhead Integer$$
|
|
The argument $icode value$$ can have the following prototype
|
|
$codei%
|
|
const %Integer%& %value%
|
|
%$$
|
|
where $icode Integer$$ is any of the fundamental integer types; e.g.,
|
|
$code short int$$ and $code unsigned long$$.
|
|
Note that if C++11 is supported by this compilation,
|
|
$code unsigned long long$$ is also a fundamental integer type.
|
|
|
|
$subhead Float$$
|
|
The argument $icode value$$ can have the following prototype
|
|
$codei%
|
|
const %Float%& %value%
|
|
%$$
|
|
where $icode Float$$ is any of the fundamental floating point types; i.e.,
|
|
$code float$$, $code double$$, and $code long double$$.
|
|
|
|
$head s$$
|
|
The return value has prototype
|
|
$codei%
|
|
std::string %s%
|
|
%$$
|
|
and contains a representation of the specified $icode value$$.
|
|
|
|
$subhead Integer$$
|
|
If $icode value$$ is an $codei Integer$$,
|
|
the representation is equivalent to $codei%os% << %value%$$
|
|
where $icode os$$ is an $code std::ostringstream$$.
|
|
|
|
$subhead Float$$
|
|
If $icode value$$ is a $codei Float$$,
|
|
enough digits are used in the representation so that
|
|
the result is accurate to withing round off error.
|
|
|
|
$children%
|
|
example/utility/to_string.cpp
|
|
%$$
|
|
$head Example$$
|
|
The file $cref to_string.cpp$$
|
|
contains an example and test of this routine.
|
|
|
|
$end
|
|
*/
|
|
# include <limits>
|
|
# include <cmath>
|
|
# include <iomanip>
|
|
# include <sstream>
|
|
# include <cppad/core/cppad_assert.hpp>
|
|
|
|
# define CPPAD_SPECIALIZE_TO_STRING_INTEGER(Type) \
|
|
template <> struct to_string_struct<Type>\
|
|
{ std::string operator()(const Type& value) \
|
|
{ std::stringstream os;\
|
|
os << value;\
|
|
return os.str();\
|
|
}\
|
|
};
|
|
|
|
# define CPPAD_SPECIALIZE_TO_STRING_FLOAT(Float) \
|
|
template <> struct to_string_struct<Float>\
|
|
{ std::string operator()(const Float& value) \
|
|
{ std::stringstream os;\
|
|
int n_digits = 1 + std::numeric_limits<Float>::digits10;\
|
|
os << std::setprecision(n_digits);\
|
|
os << value;\
|
|
return os.str();\
|
|
}\
|
|
};
|
|
|
|
namespace CppAD {
|
|
|
|
// Default implementation,
|
|
// each type must define its own specilization.
|
|
template <class Type>
|
|
struct to_string_struct
|
|
{ std::string operator()(const Type& value)
|
|
{ CPPAD_ASSERT_KNOWN(
|
|
false,
|
|
"to_string is not implemented for this type"
|
|
);
|
|
// return empty string
|
|
return std::string("");
|
|
}
|
|
};
|
|
|
|
// specialization for the fundamental integer types
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed short)
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned short)
|
|
//
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed int)
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned int)
|
|
//
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long)
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long)
|
|
//
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long long)
|
|
CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long long)
|
|
|
|
// specialization for the fundamental floating point types
|
|
CPPAD_SPECIALIZE_TO_STRING_FLOAT(float)
|
|
CPPAD_SPECIALIZE_TO_STRING_FLOAT(double)
|
|
CPPAD_SPECIALIZE_TO_STRING_FLOAT(long double)
|
|
|
|
// link from function to function object in structure
|
|
template<class Type>
|
|
std::string to_string(const Type& value)
|
|
{ to_string_struct<Type> to_str;
|
|
return to_str(value);
|
|
}
|
|
}
|
|
|
|
# undef CPPAD_SPECIALIZE_TO_STRING_FLOAT
|
|
# undef CPPAD_SPECIALIZE_TO_STRING_INTEGER
|
|
# endif
|