mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-28 22:55:33 +00:00
Ported from hz::any_type to std::any.
This commit is contained in:
@@ -194,7 +194,7 @@ LIBS="$LIBS $PCRECPP_LIBS"
|
||||
# Ideally, gcc should use the "latest" standard, but it just uses the latest option.
|
||||
# TODO For now, since gtkmm3 uses dynamic exception specifications, we have
|
||||
# to enable 14 instead of 17.
|
||||
CXXFLAGS="$CXXFLAGS -std=c++14"
|
||||
CXXFLAGS="$CXXFLAGS -std=c++17"
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
/// \weakgroup applib
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // Glib::shell_quote()
|
||||
#undef throw
|
||||
|
||||
#include "smartctl_executor.h"
|
||||
|
||||
|
||||
@@ -14,12 +14,18 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <glibmm.h>
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // Glib::shell_quote()
|
||||
#undef throw
|
||||
|
||||
#include "executor_factory.h"
|
||||
#include "storage_device.h"
|
||||
#include "rconfig/rconfig_mini.h"
|
||||
#include "app_pcrecpp.h"
|
||||
#include "hz/string_num.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include "gsc_executor_log_window.h"
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <sstream>
|
||||
#include <cstddef> // std::size_t
|
||||
#include <gtkmm.h>
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <gtkmm.h>
|
||||
#include <gdk/gdk.h> // GDK_KEY_Escape
|
||||
#include <vector> // better use vector, it's needed by others too
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <string>
|
||||
// #include <locale.h> // _configthreadlocale (win32)
|
||||
#include <stdexcept> // std::runtime_error
|
||||
@@ -18,7 +24,6 @@
|
||||
#include <limits>
|
||||
#include <gtkmm.h>
|
||||
#include <glib.h> // g_, G*
|
||||
#include <glibmm.h> // set_application_name
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
@@ -9,10 +9,17 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <gtkmm.h>
|
||||
#include <vector>
|
||||
|
||||
#include "hz/string_algo.h" // string_split
|
||||
#include "hz/string_num.h"
|
||||
#include "hz/fs_file.h" // hz::File
|
||||
#include "hz/debug.h"
|
||||
#include "hz/scoped_ptr.h"
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
// TODO Remove this in gtkmm4.
|
||||
#include <bits/stdc++.h> // to avoid throw() macro errors.
|
||||
#define throw(a) // glibmm uses dynamic exception specifications, remove them.
|
||||
#include <glibmm.h> // NOT NEEDED
|
||||
#undef throw
|
||||
|
||||
#include <map>
|
||||
#include <gtkmm.h>
|
||||
#include <gdk/gdk.h> // GDK_KEY_Escape
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
AM_CPPFLAGS = $(all_includes)
|
||||
METASOURCES = AUTO
|
||||
|
||||
noinst_HEADERS = any_convert.h any_type.h any_type_holder.h ascii.h \
|
||||
noinst_HEADERS = ascii.h \
|
||||
bad_cast_exception.h bin2ascii_encoder.h common_types.h cstdint.h cstdint_impl_msvc.h \
|
||||
data_file.h debug.h env_tools.h errno_string.h error.h error_holder.h \
|
||||
format_unit.h fs_common.h fs_dir.h fs_dir_platform.h fs_error_holder.h \
|
||||
@@ -14,7 +14,6 @@ noinst_HEADERS = any_convert.h any_type.h any_type_holder.h ascii.h \
|
||||
sync_policy_glib.h sync_policy_glibmm.h sync_policy_pthread.h \
|
||||
sync_policy_win32.h system_specific.h type_categories.h type_properties.h win32_tools.h
|
||||
|
||||
any_type_test_SOURCES = any_type_test.cpp
|
||||
bin2ascii_encoder_test_SOURCES = bin2ascii_encoder_test.cpp
|
||||
errno_string_test_SOURCES = errno_string_test.cpp
|
||||
format_unit_test_SOURCES = format_unit_test.cpp
|
||||
@@ -31,7 +30,7 @@ sync_multilock_test_SOURCES = sync_multilock_test.cpp
|
||||
# we don't list them in a separate variable because otherwise kdevelop won't see them.
|
||||
noinst_PROGRAMS =
|
||||
if ENABLE_TESTS
|
||||
noinst_PROGRAMS += any_type_test bin2ascii_encoder_test errno_string_test \
|
||||
noinst_PROGRAMS += bin2ascii_encoder_test errno_string_test \
|
||||
format_unit_test fs_dir_test fs_file_test fs_path_test string_algo_test string_num_test \
|
||||
string_wcmatch_test sync_test sync_multilock_test
|
||||
endif
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_zlib.txt file
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup hz
|
||||
/// \weakgroup hz
|
||||
/// @{
|
||||
|
||||
#ifndef HZ_ANY_CONVERT_H
|
||||
#define HZ_ANY_CONVERT_H
|
||||
|
||||
#include "hz_config.h" // feature macros
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "string_num.h" // string_is_numeric(), number_to_string()
|
||||
#include "type_categories.h" // type_check_category
|
||||
|
||||
|
||||
/// \file
|
||||
/// Loose conversions:
|
||||
/// Try to convert any type to any other type as long as specialization
|
||||
/// for any_convert is defined.
|
||||
/// String conversions to numbers are _not_ strictly checked.
|
||||
/// Numeric types are converted by static_cast between each other.
|
||||
|
||||
|
||||
|
||||
|
||||
namespace hz {
|
||||
|
||||
|
||||
|
||||
|
||||
/// This can be used for inheritance to provide a const static \c value member
|
||||
/// that is either true or false.
|
||||
template<bool v = false>
|
||||
struct AnyConvertibleValue {
|
||||
static const bool value = v;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Convert \c from to \c to using loose conversion methods.
|
||||
template<typename From, typename To>
|
||||
inline bool any_convert(From from, To& to)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// Convert \c from to \c to using loose conversion methods.
|
||||
/// This is a same-type specialization.
|
||||
template<typename From>
|
||||
inline bool any_convert(From from, From& to)
|
||||
{
|
||||
to = from;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// The structure that says whether type \c From is convertible to type \c To
|
||||
/// using loose conversion methods.
|
||||
/// This is the master struct, defaults to non-convertible.
|
||||
template<typename From, typename To>
|
||||
struct any_convertible : public AnyConvertibleValue<false> { };
|
||||
|
||||
|
||||
/// The structure that says whether type \c From is convertible to type \c To
|
||||
/// using loose conversion methods.
|
||||
// Same-type specialization
|
||||
template<typename From>
|
||||
struct any_convertible<From, From> : public AnyConvertibleValue<true> { };
|
||||
|
||||
|
||||
// specific type specs - see below.
|
||||
|
||||
|
||||
/// Define \c any_convertible specialization for \c from_type and \c to_type, saying that
|
||||
/// they're convertible. Also print \c any_convert function header.
|
||||
#define DEFINE_ANY_CONVERT_SPEC(from_type, to_type) \
|
||||
template<> \
|
||||
struct any_convertible<from_type, to_type> : public AnyConvertibleValue<true> { }; \
|
||||
\
|
||||
template<> \
|
||||
inline bool any_convert<from_type, to_type>(from_type from, to_type& to) \
|
||||
|
||||
|
||||
|
||||
/// Define \c any_convertible and \c any_convert specializations using static_cast.
|
||||
#define DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, to_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC(from_type, to_type) \
|
||||
{ \
|
||||
to = static_cast<to_type>(from); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
/// Define \c any_convertible and \c any_convert specializations using static_cast using bool.
|
||||
#define DEFINE_ANY_CONVERT_SPEC_STATIC_TOBOOL(from_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC(from_type, bool) \
|
||||
{ \
|
||||
to = static_cast<bool>(static_cast<int>(from)); /* this disables gcc warning about unsafe != */ \
|
||||
return true; \
|
||||
}
|
||||
|
||||
/// Define \c any_convertible and \c any_convert specializations using hz::number_to_string().
|
||||
#define DEFINE_ANY_CONVERT_SPEC_NUMTOSTRING(from_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC(from_type, std::string) \
|
||||
{ \
|
||||
to = hz::number_to_string(from); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
/// Define \c any_convertible and \c any_convert specializations using hz::string_is_numeric().
|
||||
#define DEFINE_ANY_CONVERT_SPEC_STRINGTONUM(to_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC(std::string, to_type) \
|
||||
{ \
|
||||
return hz::string_is_numeric(from, to, false); \
|
||||
} \
|
||||
DEFINE_ANY_CONVERT_SPEC(const std::string&, to_type) \
|
||||
{ \
|
||||
return hz::string_is_numeric(from, to, false); \
|
||||
}
|
||||
|
||||
|
||||
/// Define \c any_convertible and \c any_convert specializations for all built-in types as \c To.
|
||||
#define DEFINE_ANY_CONVERT_SPEC_ALL(from_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC_TOBOOL(from_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, char) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, signed char) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, unsigned char) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, wchar_t) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, short int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, unsigned short int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, unsigned int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, long int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, unsigned long int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, long long int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, unsigned long long int) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, double) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, float) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STATIC(from_type, long double) \
|
||||
DEFINE_ANY_CONVERT_SPEC_NUMTOSTRING(from_type) \
|
||||
DEFINE_ANY_CONVERT_SPEC_STRINGTONUM(from_type)
|
||||
|
||||
|
||||
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(bool)
|
||||
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(char)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(signed char)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(unsigned char)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(wchar_t)
|
||||
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(short int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(unsigned short int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(unsigned int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(long int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(unsigned long int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(long long int)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(unsigned long long int)
|
||||
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(double)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(float)
|
||||
DEFINE_ANY_CONVERT_SPEC_ALL(long double)
|
||||
|
||||
|
||||
|
||||
#undef DEFINE_ANY_CONVERT_SPEC
|
||||
#undef DEFINE_ANY_CONVERT_SPEC_STATIC
|
||||
#undef DEFINE_ANY_CONVERT_SPEC_NUMTOSTRING
|
||||
#undef DEFINE_ANY_CONVERT_SPEC_STRINGTONUM
|
||||
#undef DEFINE_ANY_CONVERT_SPEC_ALL
|
||||
|
||||
|
||||
|
||||
|
||||
} // ns
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
@@ -1,424 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2000 - 2010 Kevlin Henney
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_boost_1_0.txt file
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Kevlin Henney
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup hz
|
||||
/// \weakgroup hz
|
||||
/// @{
|
||||
|
||||
#ifndef HZ_ANY_TYPE_H
|
||||
#define HZ_ANY_TYPE_H
|
||||
|
||||
#include "hz_config.h" // feature macros
|
||||
|
||||
/**
|
||||
\file
|
||||
any_type library (any type one-element container), based on boost::any.
|
||||
|
||||
Original notes and copyright info follow:
|
||||
|
||||
// what: variant type boost::any
|
||||
// who: contributed by Kevlin Henney,
|
||||
// with features contributed and bugs found by
|
||||
// Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
|
||||
// when: July 2001
|
||||
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
|
||||
|
||||
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
|
||||
//
|
||||
// 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)
|
||||
|
||||
|
||||
// Compilation options:
|
||||
// - Define DISABLE_ANY_CONVERT=1 to disable all .convert functions
|
||||
// (avoids dependency on any_convert.h)
|
||||
*/
|
||||
|
||||
|
||||
#include <typeinfo> // std::type_info
|
||||
#include <iosfwd> // std::ostream
|
||||
#include <string> // to enable std::string printing. <string> is included already from any_type_holder.h.
|
||||
|
||||
#include "type_properties.h"
|
||||
#include "bad_cast_exception.h"
|
||||
#include "any_type_holder.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace hz {
|
||||
|
||||
|
||||
|
||||
/// An object of this type can contain any variable of any type in it.
|
||||
class any_type {
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
any_type()
|
||||
: content(0)
|
||||
{ }
|
||||
|
||||
/// Construct from a value
|
||||
template<typename ValueType>
|
||||
any_type(const ValueType& value)
|
||||
: content(new internal::AnyHolder<ValueType>(value))
|
||||
{ }
|
||||
|
||||
/// Copy constructor
|
||||
any_type(const any_type& other)
|
||||
: content(other.content ? other.content->clone() : 0)
|
||||
{ }
|
||||
|
||||
/// Destructor
|
||||
~any_type()
|
||||
{
|
||||
delete content;
|
||||
}
|
||||
|
||||
/// Swap *this with rhs
|
||||
inline any_type& swap(any_type& rhs);
|
||||
|
||||
|
||||
/// Check whether the wrapped variable is set
|
||||
bool empty() const
|
||||
{
|
||||
return !content;
|
||||
}
|
||||
|
||||
/// Remove the wrapped variable
|
||||
void clear()
|
||||
{
|
||||
delete content;
|
||||
content = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Get type info of the wrapped variable
|
||||
const std::type_info& type() const
|
||||
{
|
||||
return (content ? content->type() : typeid(void));
|
||||
}
|
||||
|
||||
|
||||
/// Check whether the wrapped variable is of type T.
|
||||
template<typename T> inline
|
||||
bool is_type() const; // e.g. is_type<int>
|
||||
|
||||
|
||||
|
||||
/// Get the value into a variable of _exactly_ the same type.
|
||||
/// \return false if casting fails
|
||||
template<typename T> inline
|
||||
bool get(T& put_it_here) const;
|
||||
|
||||
|
||||
/// Get the value using _exactly_ the same type.
|
||||
/// \throw bad_any_cast if casting fails
|
||||
template<typename T> inline
|
||||
T get() const; // this may throw if cast fails!
|
||||
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
/// Convert the value into a castable type using any_convert().
|
||||
template<typename T> inline
|
||||
bool convert(T& val) const;
|
||||
|
||||
/// Convert the value into a castable type using any_convert().
|
||||
/// \throw bad_any_cast if casting fails
|
||||
template<typename T> inline
|
||||
T convert() const;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/// Assignment operator from specific type
|
||||
template<typename ValueType>
|
||||
any_type& operator= (const ValueType& value)
|
||||
{
|
||||
delete content;
|
||||
content = new internal::AnyHolder<ValueType>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Assignment operator from another any_type
|
||||
any_type& operator= (const any_type& other)
|
||||
{
|
||||
delete content;
|
||||
content = other.content->clone();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// A helper class for easy operator<<() usage.
|
||||
struct StreamHelper {
|
||||
StreamHelper(internal::AnyHolderBase* c) : content(c) { }
|
||||
internal::AnyHolderBase* content;
|
||||
};
|
||||
|
||||
|
||||
/// A helper function to send any_type to a stream.
|
||||
/// Example: std::cerr << any_type_object.to_stream()
|
||||
StreamHelper to_stream() const
|
||||
{
|
||||
return StreamHelper(content);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// helper classes for enabling <<.
|
||||
|
||||
/// A helper struct for operator<<()
|
||||
template<typename T>
|
||||
struct is_default_printable
|
||||
: public type_integral_constant<bool, (type_is_integral<T>::value
|
||||
|| type_is_floating_point<T>::value || type_is_pointer<T>::value)> { };
|
||||
|
||||
|
||||
/// A helper struct for operator<<()
|
||||
template<bool b>
|
||||
struct printable {
|
||||
static const bool value = b;
|
||||
};
|
||||
|
||||
/// A helper struct for operator<<().
|
||||
// You may specialize this to <A>, with "public printable<true>" to enable default printing
|
||||
template<typename T>
|
||||
struct set_printable : public printable<false> { };
|
||||
|
||||
/// A helper struct for operator<<()
|
||||
template<typename T>
|
||||
struct is_printable {
|
||||
static const bool value = (is_default_printable<T>::value || set_printable<T>::value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
internal::AnyHolderBase* content; ///< Pointer to internal::AnyHolder<T>
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Operator<<() for any_type::StreamHelper. See any_type::to_stream().
|
||||
inline std::ostream& operator<< (std::ostream& os, const any_type::StreamHelper& sh)
|
||||
{
|
||||
if (sh.content)
|
||||
sh.content->to_stream(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// This is thrown in case of bad reference casts
|
||||
DEFINE_BAD_CAST_EXCEPTION(bad_any_cast,
|
||||
"Data type mismatch for AnyType. Original type: \"%s\", requested type: \"%s\".",
|
||||
"Data type mismatch for AnyType.");
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// any_cast operators
|
||||
|
||||
|
||||
|
||||
/// Cast a "pointer to any_type" to a "pointer to value_type"
|
||||
template<typename ValueType>
|
||||
ValueType any_cast(any_type* operand)
|
||||
{
|
||||
typedef typename type_remove_pointer<ValueType>::type nopointer;
|
||||
|
||||
if (operand && operand->content
|
||||
&& operand->type() == typeid(nopointer)
|
||||
) {
|
||||
return &static_cast<internal::AnyHolder<nopointer>*>(operand->content)->value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Cast a "pointer to any_type" to a "pointer to value_type"
|
||||
template<typename ValueType>
|
||||
const ValueType any_cast(const any_type* operand)
|
||||
{
|
||||
return any_cast<ValueType>(const_cast<any_type*>(operand));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// Cast an any_type object to value_type
|
||||
template<typename ValueType>
|
||||
ValueType any_cast(any_type& operand)
|
||||
{
|
||||
typedef typename type_remove_reference<ValueType>::type nonref;
|
||||
|
||||
if (!operand.content)
|
||||
throw bad_any_cast(operand.type(), typeid(nonref));
|
||||
|
||||
if (operand.type() != typeid(nonref))
|
||||
throw bad_any_cast(operand.type(), typeid(nonref));
|
||||
|
||||
return static_cast<internal::AnyHolder<nonref>*>(operand.content)->value;
|
||||
}
|
||||
|
||||
|
||||
/// Cast an any_type object to value_type
|
||||
template<typename ValueType>
|
||||
ValueType any_cast(const any_type& operand)
|
||||
{
|
||||
typedef typename type_remove_reference<ValueType>::type nonref;
|
||||
|
||||
if (!operand.content)
|
||||
throw bad_any_cast(operand.type(), typeid(nonref));
|
||||
|
||||
if (operand.type() != typeid(nonref))
|
||||
throw bad_any_cast(operand.type(), typeid(nonref));
|
||||
|
||||
return static_cast<const internal::AnyHolder<nonref>*>(operand.content)->value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
|
||||
inline any_type& any_type::swap(any_type& rhs)
|
||||
{
|
||||
// don't use std::swap(), we don't need <algorithm> just for one function.
|
||||
internal::AnyHolderBase* tmp = rhs.content;
|
||||
rhs.content = content;
|
||||
content = tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline
|
||||
bool any_type::is_type() const
|
||||
{
|
||||
// without rtti, any_cast<T*> will always return true.
|
||||
return static_cast<bool>(any_cast<T*>(this));
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline
|
||||
bool any_type::get(T& put_it_here) const
|
||||
{
|
||||
T* a = any_cast<T*>(this);
|
||||
if (!a)
|
||||
return false;
|
||||
put_it_here = *a;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline
|
||||
T any_type::get() const
|
||||
{
|
||||
return any_cast<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
|
||||
template<typename T> inline
|
||||
bool any_type::convert(T& val) const
|
||||
{
|
||||
return (content ? content->convert(val) : false);
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline
|
||||
T any_type::convert() const
|
||||
{
|
||||
typedef typename type_remove_reference<T>::type nonref;
|
||||
nonref result;
|
||||
if (!this->convert(result))
|
||||
throw bad_any_cast(this->type(), typeid(nonref));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
/// You may specialize this for <T, true> to enable custom printing.
|
||||
template <class ValueType, bool b = !any_type::is_printable<ValueType>::value >
|
||||
struct AnyPrinter {
|
||||
static void to_stream(std::ostream& os, const ValueType& value)
|
||||
{
|
||||
os << "[non-representable]";
|
||||
}
|
||||
};
|
||||
|
||||
/// Specialization
|
||||
template <class ValueType>
|
||||
struct AnyPrinter<ValueType, false> {
|
||||
static void to_stream(std::ostream& os, const ValueType& value)
|
||||
{
|
||||
os << value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename ValueType> inline
|
||||
void AnyHolder<ValueType>::to_stream(std::ostream& os) const
|
||||
{
|
||||
AnyPrinter<ValueType>::to_stream(os, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Do NOT define operator<< for any_type !
|
||||
// Since any C++ type is implicitly convertable to any_type, and it will
|
||||
// serve all unrelated types and may even end up in an endless loop.
|
||||
|
||||
|
||||
|
||||
/// Use this to add supported types to any_type::to_stream().
|
||||
/// Any type may be added if it supports operator <<.
|
||||
#define ANY_TYPE_SET_PRINTABLE(type, truefalse) \
|
||||
namespace hz { \
|
||||
template<> struct any_type::set_printable<type> : public any_type::printable<truefalse> { }; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // ns
|
||||
|
||||
|
||||
|
||||
/// Make std::string printable using any_type::to_stream().
|
||||
ANY_TYPE_SET_PRINTABLE(std::string, true)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
@@ -1,169 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2000 - 2010 Kevlin Henney
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_boost_1_0.txt file
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Kevlin Henney
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup hz
|
||||
/// \weakgroup hz
|
||||
/// @{
|
||||
|
||||
#ifndef HZ_ANY_TYPE_HOLDER_H
|
||||
#define HZ_ANY_TYPE_HOLDER_H
|
||||
|
||||
#include "hz_config.h" // feature macros
|
||||
|
||||
/**
|
||||
\file
|
||||
Internal header, do not include manually.
|
||||
*/
|
||||
|
||||
#include <typeinfo> // std::type_info
|
||||
#include <iosfwd> // std::ostream
|
||||
#include <string>
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
#include "any_convert.h" // any_convert
|
||||
#endif
|
||||
|
||||
|
||||
namespace hz {
|
||||
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
|
||||
|
||||
/// Base class for content of hz::any_type
|
||||
struct AnyHolderBase {
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~AnyHolderBase() { }
|
||||
|
||||
/// Get std::type_info for the wrapped variable
|
||||
virtual const std::type_info& type() const = 0;
|
||||
|
||||
/// Clone the wrapped variable
|
||||
virtual AnyHolderBase* clone() const = 0;
|
||||
|
||||
/// Send the wrapped variable to std::ostream
|
||||
virtual void to_stream(std::ostream& os) const = 0;
|
||||
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
|
||||
/// Convert the wrapped variable to argument type
|
||||
virtual bool convert(bool& val) const = 0;
|
||||
|
||||
virtual bool convert(char& val) const = 0;
|
||||
virtual bool convert(signed char& val) const = 0;
|
||||
virtual bool convert(unsigned char& val) const = 0;
|
||||
virtual bool convert(wchar_t& val) const = 0;
|
||||
|
||||
virtual bool convert(short int& val) const = 0;
|
||||
virtual bool convert(unsigned short int& val) const = 0;
|
||||
virtual bool convert(int& val) const = 0;
|
||||
virtual bool convert(unsigned int& val) const = 0;
|
||||
virtual bool convert(long int& val) const = 0;
|
||||
virtual bool convert(unsigned long int& val) const = 0;
|
||||
virtual bool convert(long long int& val) const = 0;
|
||||
virtual bool convert(unsigned long long int& val) const = 0;
|
||||
|
||||
virtual bool convert(double& val) const = 0;
|
||||
virtual bool convert(float& val) const = 0;
|
||||
virtual bool convert(long double& val) const = 0;
|
||||
|
||||
virtual bool convert(std::string& val) const = 0;
|
||||
|
||||
#endif // DISABLE_ANY_CONVERT
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Child class for content, holds the actual value
|
||||
template<typename ValueType>
|
||||
struct AnyHolder : public AnyHolderBase {
|
||||
|
||||
/// Type of the wrapped variable
|
||||
typedef ValueType value_type;
|
||||
|
||||
/// Constructor
|
||||
AnyHolder(const ValueType& val)
|
||||
: value(val)
|
||||
{ }
|
||||
|
||||
|
||||
/// Get std::type_info object for the wrapped variable
|
||||
const std::type_info& type() const
|
||||
{
|
||||
return typeid(ValueType);
|
||||
}
|
||||
|
||||
/// Clone the wrapped variable. Note that this is not a deep clone.
|
||||
AnyHolderBase* clone() const
|
||||
{
|
||||
return new AnyHolder(value);
|
||||
}
|
||||
|
||||
/// Send the wrapped variable to std::ostream
|
||||
inline void to_stream(std::ostream& os) const;
|
||||
// {
|
||||
// AnyPrinter<ValueType>::to_stream(os, value);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
|
||||
// Reimplemented from AnyHolderBase
|
||||
bool convert(bool& val) const { return any_convert(value, val); }
|
||||
|
||||
bool convert(char& val) const { return any_convert(value, val); }
|
||||
bool convert(signed char& val) const { return any_convert(value, val); }
|
||||
bool convert(unsigned char& val) const { return any_convert(value, val); }
|
||||
bool convert(wchar_t& val) const { return any_convert(value, val); }
|
||||
|
||||
bool convert(short int& val) const { return any_convert(value, val); }
|
||||
bool convert(unsigned short int& val) const { return any_convert(value, val); }
|
||||
bool convert(int& val) const { return any_convert(value, val); }
|
||||
bool convert(unsigned int& val) const { return any_convert(value, val); }
|
||||
bool convert(long int& val) const { return any_convert(value, val); }
|
||||
bool convert(unsigned long int& val) const { return any_convert(value, val); }
|
||||
bool convert(long long int& val) const { return any_convert(value, val); }
|
||||
bool convert(unsigned long long int& val) const { return any_convert(value, val); }
|
||||
|
||||
bool convert(double& val) const { return any_convert(value, val); }
|
||||
bool convert(float& val) const { return any_convert(value, val); }
|
||||
bool convert(long double& val) const { return any_convert(value, val); }
|
||||
|
||||
bool convert(std::string& val) const { return any_convert(value, val); }
|
||||
|
||||
#endif // DISABLE_ANY_CONVERT
|
||||
|
||||
|
||||
ValueType value; ///< The wrapped data
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
@@ -1,160 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_unlicense.txt
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup hz_tests
|
||||
/// \weakgroup hz_tests
|
||||
/// @{
|
||||
|
||||
// disable libdebug, we don't link to it
|
||||
#undef HZ_USE_LIBDEBUG
|
||||
#define HZ_USE_LIBDEBUG 0
|
||||
// enable libdebug emulation through std::cerr
|
||||
#undef HZ_EMULATE_LIBDEBUG
|
||||
#define HZ_EMULATE_LIBDEBUG 1
|
||||
|
||||
|
||||
// define this to disable any_convert.h dependency
|
||||
// #define DISABLE_ANY_CONVERT
|
||||
|
||||
// The first header should be then one we're testing, to avoid missing
|
||||
// header pitfalls.
|
||||
#include "any_type.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace hz;
|
||||
|
||||
|
||||
/// TestClass test structure
|
||||
struct TestClass {
|
||||
|
||||
typedef std::list<any_type> any_list;
|
||||
|
||||
|
||||
void append_int(any_list& values, int value)
|
||||
{
|
||||
any_type to_append = value;
|
||||
values.push_back(to_append);
|
||||
}
|
||||
|
||||
|
||||
void append_string(any_list& values, const std::string& value)
|
||||
{
|
||||
values.push_back(value);
|
||||
}
|
||||
|
||||
|
||||
void append_char_ptr(any_list& values, const char* value)
|
||||
{
|
||||
values.push_back(value);
|
||||
}
|
||||
|
||||
|
||||
void append_any(any_list& values, const any_type& value)
|
||||
{
|
||||
values.push_back(value);
|
||||
}
|
||||
|
||||
|
||||
void append_nothing(any_list& values)
|
||||
{
|
||||
values.push_back(any_type());
|
||||
}
|
||||
|
||||
|
||||
std::string get_string(any_list& values)
|
||||
{
|
||||
any_type a = values.back();
|
||||
|
||||
any_cast<std::string>(a);
|
||||
|
||||
std::string b;
|
||||
a.get(b);
|
||||
|
||||
a.get<std::string>();
|
||||
|
||||
if (a.is_type<std::string>())
|
||||
return any_cast<std::string>(a);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/// enable printing TestClass.
|
||||
/// This needs operator<< and and ANY_TYPE_SET_PRINTABLE specialization.
|
||||
inline std::ostream& operator<< (std::ostream& os, TestClass a)
|
||||
{
|
||||
return (os << "TestClass\n");
|
||||
}
|
||||
|
||||
ANY_TYPE_SET_PRINTABLE(TestClass, true);
|
||||
|
||||
|
||||
|
||||
|
||||
/// Main function for the test
|
||||
int main()
|
||||
{
|
||||
|
||||
any_type a1;
|
||||
a1 = 4;
|
||||
std::cerr << a1.to_stream() << "\n";
|
||||
|
||||
|
||||
TestClass b;
|
||||
any_type b1 = b;
|
||||
// std::cerr << b;
|
||||
std::cerr << b1.to_stream() << "\n";
|
||||
|
||||
|
||||
|
||||
#if !(defined DISABLE_ANY_CONVERT && DISABLE_ANY_CONVERT)
|
||||
|
||||
any_type a2 = std::string("5.444");
|
||||
double a2val = 0;
|
||||
std::cerr << "conversion " << (a2.convert(a2val) ? "succeeded" : "failed") << ", ";
|
||||
std::cerr << "value: " << a2val << "\n";
|
||||
|
||||
any_type a3 = 6.55;
|
||||
std::string a3val;
|
||||
std::cerr << "conversion " << (a3.convert(a3val) ? "succeeded" : "failed") << ", ";
|
||||
std::cerr << "value: " << a3val << "\n";
|
||||
|
||||
any_type a4 = std::string("7");
|
||||
int a4val = 0;
|
||||
std::cerr << "conversion " << (a4.convert(a4val) ? "succeeded" : "failed") << ", ";
|
||||
std::cerr << "value: " << a4val << "\n";
|
||||
|
||||
any_type a5 = 'a';
|
||||
double a5val = 0;
|
||||
std::cerr << "conversion " << (a5.convert(a5val) ? "succeeded" : "failed") << ", ";
|
||||
std::cerr << "value: " << a5val << "\n";
|
||||
|
||||
|
||||
char b1val = 0;
|
||||
std::cerr << "conversion " << (b1.convert(b1val) ? "succeeded" : "failed") << ", ";
|
||||
std::cerr << "value: " << int(b1val) << "\n";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// @}
|
||||
@@ -447,39 +447,6 @@ T get_data(const std::string& path)
|
||||
|
||||
|
||||
|
||||
/// Similar to get_data(), but with looser conversion - can convert between
|
||||
/// C++ built-in types and std::string. Uses hz::any_convert<>.
|
||||
/// \return false if casting failed, or empty or invalid type.
|
||||
template<typename T> inline
|
||||
bool convert_data(const std::string& path, T& put_it_here) // returns false if cast failed
|
||||
{
|
||||
ConfigLockPolicy::ScopedLock locker(RootHolder::mutex);
|
||||
|
||||
node_ptr node = get_node(path);
|
||||
if (!node)
|
||||
return false; // no such node
|
||||
return node->convert_data(put_it_here);
|
||||
}
|
||||
|
||||
|
||||
/// Similar to get_data(), but with looser conversion - can convert between
|
||||
/// C++ built-in types and std::string. Uses hz::any_convert<>.
|
||||
/// \throw rmn::no_such_node No such node
|
||||
/// \throw rmn::empty_data_retrieval Data is empty
|
||||
/// \throw rmn::type_mismatch Type mismatch
|
||||
template<typename T> inline
|
||||
T convert_data(const std::string& path)
|
||||
{
|
||||
ConfigLockPolicy::ScopedLock locker(RootHolder::mutex);
|
||||
|
||||
node_ptr node = get_node(path);
|
||||
if (!node)
|
||||
throw rmn::no_such_node(path);
|
||||
return node->convert_data<T>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -66,17 +66,16 @@ int main()
|
||||
|
||||
// loose typing:
|
||||
|
||||
int int_var2 = 0;
|
||||
rconfig::convert_data("app/int_var2", int_var2); // this will do the type conversion
|
||||
std::cerr << "app/int_var2: " << int_var2 << "\n"; // this will get out 11, not 10 (default)
|
||||
// int int_var2 = 0;
|
||||
// rconfig::convert_data("app/int_var2", int_var2); // this will do the type conversion
|
||||
// std::cerr << "app/int_var2: " << int_var2 << "\n"; // this will get out 11, not 10 (default)
|
||||
|
||||
// std::cerr << "app/some_string1: " << rconfig::convert_data<std::string>("app/some_string1") << "\n";
|
||||
|
||||
|
||||
std::cerr << "app/some_string1: " << rconfig::convert_data<std::string>("app/some_string1") << "\n";
|
||||
|
||||
|
||||
std::string huh;
|
||||
rconfig::convert_data("app/huh", huh); // float -> string conversion, should work.
|
||||
std::cerr << "app/huh: " << huh << "\n";
|
||||
// std::string huh;
|
||||
// rconfig::convert_data("app/huh", huh); // float -> string conversion, should work.
|
||||
// std::cerr << "app/huh: " << huh << "\n";
|
||||
|
||||
|
||||
std::cerr << "\"app/empty\" exists: " << std::boolalpha << rconfig::data_is_empty("app/empty") << "\n";
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd> // std::ostream
|
||||
#include <any>
|
||||
|
||||
#include "hz/any_type.h"
|
||||
|
||||
#include "resource_data_types.h"
|
||||
#include "resource_exception.h"
|
||||
@@ -56,7 +56,11 @@ struct ResourceDataAnyDumper {
|
||||
/// Dump resource data into \c os
|
||||
void dump(std::ostream& os) const
|
||||
{
|
||||
os << obj->data_.to_stream();
|
||||
const std::type_info& type = obj->data_.type();
|
||||
if (type == typeid(char)) {
|
||||
os << std::any_cast<char>(std::any_cast<char>(obj->data_));
|
||||
}
|
||||
// TODO other types.
|
||||
}
|
||||
|
||||
T* obj; ///< ResourceDataAny object
|
||||
@@ -98,14 +102,14 @@ class ResourceDataAny {
|
||||
/// Check whether data is empty
|
||||
bool data_is_empty() const
|
||||
{
|
||||
return data_.empty();
|
||||
return !data_.has_value();
|
||||
}
|
||||
|
||||
|
||||
/// Clear the data, making it empty
|
||||
void clear_data()
|
||||
{
|
||||
data_.clear();
|
||||
data_.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +135,7 @@ class ResourceDataAny {
|
||||
template<typename T>
|
||||
inline bool data_is_type() const
|
||||
{
|
||||
return data_.template is_type<T>();
|
||||
return data_.type() == typeid(T);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +144,11 @@ class ResourceDataAny {
|
||||
template<typename T>
|
||||
inline bool get_data(T& put_it_here) const
|
||||
{
|
||||
return data_.get(put_it_here); // returns false if empty or invalid type
|
||||
if (const T* value = std::any_cast<T>(&data_)) {
|
||||
put_it_here = *value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,52 +158,19 @@ class ResourceDataAny {
|
||||
template<typename T>
|
||||
T get_data() const
|
||||
{
|
||||
if (data_.empty())
|
||||
if (!data_.has_value())
|
||||
throw empty_data_retrieval();
|
||||
|
||||
try {
|
||||
// template is needed for gcc 3.3
|
||||
return data_.template get<T>(); // won't work if empty or invalid type
|
||||
return std::any_cast<T>(data_);
|
||||
}
|
||||
catch (hz::bad_any_cast& e) { // convert any_type exception to rmn exception.
|
||||
catch (std::bad_any_cast& e) { // convert std::any exception to rmn exception.
|
||||
throw type_mismatch(data_.type(), typeid(T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Similar to get_data(), but with looser conversion - can convert between
|
||||
/// C++ built-in types and std::string. Uses hz::any_convert<>.
|
||||
/// \return false if casting failed, or empty or invalid type.
|
||||
template<typename T>
|
||||
inline bool convert_data(T& put_it_here) const
|
||||
{
|
||||
return data_.convert(put_it_here);
|
||||
}
|
||||
|
||||
|
||||
/// Similar to get_data(), but with looser conversion - can convert between
|
||||
/// C++ built-in types and std::string. Uses hz::any_convert<>.
|
||||
/// \throw rmn::empty_data_retrieval Data is empty
|
||||
/// \throw rmn::type_mismatch Type mismatch
|
||||
template<typename T>
|
||||
T convert_data() const
|
||||
{
|
||||
if (data_.empty())
|
||||
throw empty_data_retrieval();
|
||||
|
||||
try {
|
||||
// Note: This throws only if RTTI is enabled.
|
||||
// template is needed for gcc 3.3
|
||||
return data_.template convert<T>(); // won't work if empty or invalid type
|
||||
}
|
||||
catch (hz::bad_any_cast& e) {
|
||||
throw type_convert_error(data_.type(), typeid(T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
friend struct ResourceDataAnyDumper;
|
||||
|
||||
@@ -210,7 +185,7 @@ class ResourceDataAny {
|
||||
|
||||
private:
|
||||
|
||||
hz::any_type data_; ///< The data
|
||||
std::any data_; ///< The data
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -173,26 +173,6 @@ class ResourceDataOne {
|
||||
}
|
||||
|
||||
|
||||
/// Get data (use static_cast conversion).
|
||||
template<typename T>
|
||||
inline bool convert_data(T& put_it_here) const // returns false if cast failed
|
||||
{
|
||||
put_it_here = static_cast<T>(data_);
|
||||
return true; // static_cast will check it at compile-time.
|
||||
}
|
||||
|
||||
|
||||
/// Get a copy of data (use static_cast conversion).
|
||||
/// \throw rmn::empty_data_retrieval if data is empty
|
||||
template<typename T>
|
||||
T convert_data() const
|
||||
{
|
||||
if (empty_)
|
||||
throw empty_data_retrieval();
|
||||
return static_cast<T>(data_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
friend struct ResourceDataOneDumper;
|
||||
|
||||
Reference in New Issue
Block a user