fix: #159 Merge branch 'conversion-precedence'

This commit is contained in:
ToruNiina 2021-05-14 20:10:03 +09:00
commit 7339ce39d5
3 changed files with 42 additions and 11 deletions

View File

@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
# g++-4.8 and 4.9 are tested on Travis.CI.
compiler: ['g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5']
compiler: ['g++-11', 'g++-10', 'g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5']
standard: ['11', '14', '17', '20']
exclude:
- {compiler: 'g++-5', standard: '17'}
@ -59,6 +59,7 @@ jobs:
- {compiler: '6.0', standard: '20'}
- {compiler: '7', standard: '20'}
- {compiler: '8', standard: '20'}
- {compiler: '9', standard: '20'}
steps:
- name: Checkout
uses: actions/checkout@v2

View File

@ -255,16 +255,19 @@ get(const basic_value<C, M, V>&);
// toml::from<T>::from_toml(v)
template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V,
std::size_t S = sizeof(::toml::from<T>)>
T get(const basic_value<C, M, V>&);
template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::has_specialized_from<T>::value, T>
get(const basic_value<C, M, V>&);
// T(const toml::value&) and T is not toml::basic_value
// T(const toml::value&) and T is not toml::basic_value,
// and it does not have `from<T>` nor `from_toml`.
template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::conjunction<
detail::negation<detail::is_basic_value<T>>,
std::is_constructible<T, const basic_value<C, M, V>&>
std::is_constructible<T, const basic_value<C, M, V>&>,
detail::negation<detail::has_from_toml_method<T, C, M, V>>,
detail::negation<detail::has_specialized_from<T>>
>::value, T>
get(const basic_value<C, M, V>&);
@ -440,9 +443,9 @@ get(const basic_value<C, M, V>& v)
return ud;
}
template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V,
std::size_t>
T get(const basic_value<C, M, V>& v)
template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::has_specialized_from<T>::value, T>
get(const basic_value<C, M, V>& v)
{
return ::toml::from<T>::from_toml(v);
}
@ -450,8 +453,10 @@ T get(const basic_value<C, M, V>& v)
template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::conjunction<
detail::negation<detail::is_basic_value<T>>,
std::is_constructible<T, const basic_value<C, M, V>&>
detail::negation<detail::is_basic_value<T>>, // T is not a toml::value
std::is_constructible<T, const basic_value<C, M, V>&>, // T is constructible from toml::value
detail::negation<detail::has_from_toml_method<T, C, M, V>>, // and T does not have T.from_toml(v);
detail::negation<detail::has_specialized_from<T>> // and T does not have toml::from<T>{};
>::value, T>
get(const basic_value<C, M, V>& v)
{

View File

@ -2,6 +2,10 @@
// Distributed under the MIT License.
#ifndef TOML11_TRAITS_HPP
#define TOML11_TRAITS_HPP
#include "from.hpp"
#include "into.hpp"
#include <chrono>
#include <forward_list>
#include <string>
@ -84,6 +88,22 @@ struct has_into_toml_method_impl
static std::false_type check(...);
};
struct has_specialized_from_impl
{
template<typename T>
static std::false_type check(...);
template<typename T, std::size_t S = sizeof(::toml::from<T>)>
static std::true_type check(::toml::from<T>*);
};
struct has_specialized_into_impl
{
template<typename T>
static std::false_type check(...);
template<typename T, std::size_t S = sizeof(::toml::into<T>)>
static std::true_type check(::toml::from<T>*);
};
/// Intel C++ compiler can not use decltype in parent class declaration, here
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
#ifdef __INTEL_COMPILER
@ -114,6 +134,11 @@ template<typename T>
struct has_into_toml_method
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};
template<typename T>
struct has_specialized_from : decltype(has_specialized_from_impl::check<T>(nullptr)){};
template<typename T>
struct has_specialized_into : decltype(has_specialized_into_impl::check<T>(nullptr)){};
#ifdef __INTEL_COMPILER
#undef decltype
#endif