Invocation: build a solution to adapt std::array
...which should ''basically work,'' since `std::array` is ''»tuple-like«'' — BUT unfortunately it has a quite distinct template signature which does not fit into the generic scheme of a product type. Obviously we'd need a partial specialisation, but even re-implementing this turns out to be damn hard, because there is no way to generate a builder method with a suitable explicit type signature directly, because such a builder would need to accept precisely N arguments of same type. This leads to a different solution approach: we can introduce an ''adapter type'', which will be layered on top of `std::array` and just expose the proper type signature so that the existing Implementation can handle the array, relying on the tuple-protocol. __Note__: this changeset adds a convenient pretty-printer for `std::array`, based on the same forward-declaration trick employed recently for `lib::Several`. You need to include 'lib/format-util.hpp' to actually use it.
This commit is contained in:
parent
8bb332cc5e
commit
0cad2dacc0
5 changed files with 245 additions and 12 deletions
|
|
@ -15,12 +15,12 @@
|
|||
/** @file format-obj.hpp
|
||||
** Simple functions to represent objects, for debugging and diagnostics.
|
||||
** The helpers provided here are rather commonplace, but written in a way
|
||||
** as to incur only modest header inclusion load. It should be OK to use
|
||||
** these even on widely used interface headers.
|
||||
** to incur only modest header inclusion load. It should be OK to use them
|
||||
** even on interface headers in widespread use.
|
||||
** - util::toString() performs a failsafe to-String conversion, thereby preferring a
|
||||
** built-in conversion operator, falling back to a lexical conversion (boost)
|
||||
** or just a unmangled and simplified type string as default.
|
||||
** - util::typedString() combines this with a always visible type display
|
||||
** or just an unmangled and simplified type string as default.
|
||||
** - util::typedString() combines this with an always visible type display
|
||||
** - lib::meta::demangleCxx() uses the built-in compiler support to translate a mangled
|
||||
** type-ID (as given by `typeid(TY).name()`) into a readable, fully qualified
|
||||
** C++ type name. This is only supported for GNU compatible compilers.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
|
@ -259,5 +260,17 @@ namespace util {
|
|||
}
|
||||
|
||||
|
||||
/** convenient pretty-printer for std::array instances */
|
||||
template<typename T, std::size_t N>
|
||||
struct StringConv<std::array<T,N>>
|
||||
{
|
||||
static std::string
|
||||
invoke (std::array<T,N> const& arr) noexcept
|
||||
{
|
||||
return util::toStringBracket (arr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace util
|
||||
#endif /*LIB_FORMAT_UTIL_H*/
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <array>
|
||||
|
||||
|
||||
|
||||
|
|
@ -96,5 +97,91 @@ namespace meta{
|
|||
};
|
||||
|
||||
|
||||
/* ===== adapt array for tuple-like signature ===== */
|
||||
|
||||
template<typename...TTT>
|
||||
struct ArrayAdapt;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename...TTT>
|
||||
struct AllSame
|
||||
: std::true_type
|
||||
{ };
|
||||
|
||||
template<typename T1, typename T2, typename...TS>
|
||||
struct AllSame<T1,T2,TS...>
|
||||
: __and_<is_same<T1,T2>
|
||||
,AllSame<T2,TS...>
|
||||
>
|
||||
{ };
|
||||
|
||||
|
||||
template<typename T, size_t N>
|
||||
struct Repeat
|
||||
{
|
||||
using Rem = typename Repeat<T, N-1>::Seq;
|
||||
using Seq = typename Prepend<T,Rem>::Seq;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Repeat<T,0>
|
||||
{
|
||||
using Seq = TySeq<>;
|
||||
};
|
||||
|
||||
template<typename T, size_t N>
|
||||
struct _Adapt
|
||||
{
|
||||
using NFold = typename Repeat<T,N>::Seq;
|
||||
using Array = typename RebindVariadic<ArrayAdapt, NFold>::Type;
|
||||
};
|
||||
|
||||
template<typename T, size_t N>
|
||||
using _AdaptArray_t = typename _Adapt<T,N>::Array;
|
||||
}
|
||||
|
||||
template<typename T, typename...TT>
|
||||
struct ArrayAdapt<T,TT...>
|
||||
: std::array<T, 1+sizeof...(TT)>
|
||||
{
|
||||
static_assert (AllSame<T,TT...>()
|
||||
,"Array can only hold elements of uniform type");
|
||||
using Array = std::array<T, 1+sizeof...(TT)>;
|
||||
|
||||
ArrayAdapt (Array const& o) : Array{o} { }
|
||||
ArrayAdapt (Array && r) : Array{move(r)} { }
|
||||
|
||||
template<typename...XS>
|
||||
ArrayAdapt (XS&& ...inits)
|
||||
: Array{std::forward<XS> (inits)...}
|
||||
{ }
|
||||
};
|
||||
|
||||
template<typename T, size_t N>
|
||||
struct TupleClosureBuilder<std::array<T,N>>
|
||||
: TupleClosureBuilder<_AdaptArray_t<T,N>>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue