Proper dispatch
This commit is contained in:
parent
91ba24703a
commit
c4ee778040
@ -16,9 +16,57 @@ namespace nb {
|
|||||||
template <typename StreamType, typename... Mixins>
|
template <typename StreamType, typename... Mixins>
|
||||||
class SmartStream;
|
class SmartStream;
|
||||||
|
|
||||||
template<typename C, typename T, typename... Mixins>
|
template<typename StreamFormat, typename U, typename Mix>
|
||||||
class SmartStream<std::basic_ostream<C, T>, Mixins...> : public virtual Mixins... {
|
struct MixinHasProcess {
|
||||||
using StreamType = std::basic_ostream<C, T>;
|
protected:
|
||||||
|
template <typename M>
|
||||||
|
static auto test(int)->decltype(
|
||||||
|
M::process(std::declval<StreamFormat&>(), std::declval<const U&>()),
|
||||||
|
std::true_type{}
|
||||||
|
);
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
static std::false_type test(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const bool value = decltype(test<Mix>(0))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename StreamFormat, typename U, typename... Mixins>
|
||||||
|
struct PackHasProcess;
|
||||||
|
|
||||||
|
template<typename StreamFormat, typename U, typename Mix>
|
||||||
|
struct PackHasProcess<StreamFormat, U, Mix> {
|
||||||
|
static const bool value = MixinHasProcess<StreamFormat, U, Mix>::value;
|
||||||
|
using type = typename std::conditional<
|
||||||
|
value,
|
||||||
|
Mix,
|
||||||
|
void
|
||||||
|
>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename StreamFormat, typename U, typename Mix1, typename... Mixins>
|
||||||
|
struct PackHasProcess<StreamFormat, U, Mix1, Mixins...> {
|
||||||
|
protected:
|
||||||
|
static const bool base_value = MixinHasProcess<StreamFormat, U, Mix1>::value;
|
||||||
|
public:
|
||||||
|
static const bool value = std::conditional<
|
||||||
|
base_value,
|
||||||
|
std::true_type,
|
||||||
|
typename PackHasProcess<StreamFormat, U, Mixins...>::value
|
||||||
|
>::type::value;
|
||||||
|
using type = typename std::conditional<
|
||||||
|
base_value,
|
||||||
|
Mix1,
|
||||||
|
typename PackHasProcess<StreamFormat, U, Mixins...>::type
|
||||||
|
>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ST, typename... Mixins>
|
||||||
|
class SmartStream<ST, Mixins...> : public virtual Mixins... {
|
||||||
|
using StreamType = typename std::conditional<
|
||||||
|
std::is_base_of<std>::value
|
||||||
|
>::type;
|
||||||
protected:
|
protected:
|
||||||
StreamType* const _stream;
|
StreamType* const _stream;
|
||||||
|
|
||||||
@ -30,13 +78,20 @@ public:
|
|||||||
using Mixins::process...;
|
using Mixins::process...;
|
||||||
|
|
||||||
template <typename U, typename StreamFmt=SmartStream<StreamType, Mixins...>>
|
template <typename U, typename StreamFmt=SmartStream<StreamType, Mixins...>>
|
||||||
static void process(SmartStream& stream, const U& val, StreamFmt* fmtas=nullptr) {
|
static typename std::enable_if<PackHasProcess<StreamFmt, U, Mixins...>::value, void>::type
|
||||||
|
toStream(SmartStream& stream, const U& val, const StreamFmt* fmtas=nullptr) {
|
||||||
|
PackHasProcess<StreamFmt, U, Mixins...>::type::process(stream, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U, typename StreamFmt=SmartStream<StreamType, Mixins...>>
|
||||||
|
static typename std::enable_if<!PackHasProcess<StreamFmt, U, Mixins...>::value, void>::type
|
||||||
|
toStream(SmartStream& stream, const U& val, const StreamFmt* fmtas=nullptr) {
|
||||||
*(stream._stream) << val;
|
*(stream._stream) << val;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ST, typename U, typename... Mixes>
|
template <typename ST, typename U, typename... Mixes>
|
||||||
friend SmartStream<ST, Mixes...>& operator<<(SmartStream<ST, Mixes...>& stream, const U& val) {
|
friend SmartStream<ST, Mixes...>& operator<<(SmartStream<ST, Mixes...>& stream, const U& val) {
|
||||||
SmartStream<ST, Mixes...>::process(stream, val);
|
SmartStream<ST, Mixes...>::toStream(stream, val);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user