Ensure argument is an output stream for the console - c++

I'm trying to make a stream manipulator for colour for use with output to the console. It works, changing the colour of text and the background:
std::cout << ConColor::Color::FgBlue << 123 << "abc"; //text is blue, sticky
The problem is with the signature:
std::ostream &FgBlue(std::ostream &);
This signature allows for derived classes, such as std::ostringstream as well, but there is no way to change the colour of a string stream. The function would change the colour of the console regardless if it was called with such an argument.
Therefore, I want to ensure the argument is something along the lines of std::cout, std::wcout, etc. I would prefer it be general in the case that more std::ostream objects are added in a future standard.
I tried many things involving std::is_same and std::is_base_of, when the former wouldn't work, just to eventually realize that it was pointless because any argument type inheriting from std::basic_ostream<> will be casted to the type I'm comparing against when passed to the function, giving false positives.
This eventually led me to my answer below (variadic template template arguments? Wow, that's a mouthful!) There are a couple problems, however:
The compiler must support variadic templates. I would prefer the solution work on MSVC.
The compiler gives cryptic errors in the case that a derived class with a different number of template arguments (such as std::ostringstream, which has 3 instead of 2) is used, as it doesn't get past the function signature.
It's possible to redirect stdout, say, to a file, so even if the argument is std::cout, the same thing as the stringstream case happens.
I encourage people to post any other solutions, hopefully better than mine, and really hopefully something that works with at least VS11.

Here's a trait for detecting std::basic_ostream instantiations:
template<typename T> struct is_basic_ostream {
template<typename U, typename V>
static char (&impl(std::basic_ostream<U, V> *))[
std::is_same<T, std::basic_ostream<U, V>>::value ? 2 : 1];
static char impl(...);
static constexpr bool value = sizeof(impl((T *)0)) == 2;
};
Use as:
template<typename T>
void foo(T &) {
static_assert(is_basic_ostream<T>::value,
"Argument must be of type std::basic_ostream<T, U>.");
}
We use template argument deduction to infer the template parameters on the (non-proper) basic_ostream base class, if any. As a more general solution, replacing U and V with a single variadic parameter would allow writing a generic is_instantiation_of trait on compilers that support variadic template parameters.
To detect whether stdout is piped to a file (which can only be detected at runtime, of course) use isatty; see how to use isatty() on cout, or can I assume that cout == file descriptor 1?

This is what I came up with after a lot of trial:
template<template<typename...> class T, typename... U>
void foo(T<U...> &os) {
static_assert(
std::is_same<
std::basic_ostream<U...>,
typename std::remove_reference<decltype(os)>::type
>::value,
"Argument must be of type std::basic_ostream<T, U>."
);
//...
}
Source code containing each of the below tests can be found here.
Source code replacing the types with similar self-made ones that are more explicit and offer more freedom (e.g., instantiation), which might be more useful for testing, can be found here.
Passing in std::cout and std::wcout makes it compile fine.
Passing in an instance of std::ostringstream causes it to complain about the number of template arguments.
Passing in an instance of std::fstream, which has the same number of template parameters, causes the static assertion to fail.
Passing in a self-made 2-parameter template class causes the static assertion to fail.
Please feel free to improve upon this any way you can.

Related

Any way for template substitution to happen before argument dependent lookup (or workarounds?)

I suppose the basic premise of this question is that I'm trying to use enable_if along with Argument Dependent Lookup (ADL), but I'm not sure if it's possible. I do see on this page that
Template argument deduction takes place after the function template name lookup (which may involve argument-dependent lookup) and before template argument substitution (which may involve SFINAE) and overload resolution.
So I imagine this won't work, but in the spirit of learning I'd like to put the question out there.
Here's an example of what I'm trying to get to happen:
#include <iostream>
namespace lib1 {
template <typename T>
void archive(T & t)
{
serialize(t);
}
}
namespace lib2 {
struct VectorInt {
int x;
int y;
};
struct VectorDouble {
double x;
double y;
};
template<typename T>
void serialize(std::enable_if<std::is_same<T, VectorInt>::value, T>::type & vect) {
std::cout << vect.x << std::endl;
}
// maybe do something different with VectorDouble. Overloading would work,
// but I'm curious if it can be made to work with enable_if
}
int main() {
lib2::VectorInt myvect;
myvect.x = 2;
lib1::archive(myvect);
}
The example is loosely based on something I'm trying to do with the cereal library. In my case I have several different types of vectors and matrices, and while I can use overloading to get functions to resolve properly, I was curious to use the enable_if feature to see if I could shorten the code.
Anyway, trying to compile that gives a message "error: variable or field 'serialize' declared void".
It's my understanding that this won't work because the enable_if is evaluated only after argument dependent lookup? Is that right?
For those that want to play around with this, I have the code up on repl.it: https://repl.it/repls/HalfBlandJumpthreading
There's two separate things going on in your example: there's (function) template argument deduction, and there's argument dependent lookup (ADL). The relationship between these two is slightly complex if you start trying to explicitly specify template parameters (hey, it's C++), you can read more here: http://en.cppreference.com/w/cpp/language/adl (in the notes section).
That said, in general in C++ it's typically better to allow function templates to deduce their arguments rather than specify them explicitly, which is what you were trying to do here anyway, so all is well.
When you do:
namespace lib1 {
template <typename T>
void archive(T & t)
{
serialize(t);
}
}
The call to serialize qualifies for ADL, and since it depends on t it is deferred until the template is instantiated since the type of t is required (this is called 2 phase lookup). When you call archive with an object of type VectorInt, the call to serialize will look in the namespace of VectorInt. Everything is working just fine. The problem is in this code:
template<typename T>
void serialize(std::enable_if<std::is_same<T, VectorInt>::value, T>::type & vect) {
std::cout << vect.x << std::endl;
}
You didn't specify template parameters explicitly, so they have to be deduced. But the form you give here does not allow deduction: http://en.cppreference.com/w/cpp/language/template_argument_deduction, see non-deduced contexts, the very first example. To try to understand better why, consider what you are asking the compiler to do: you are passing a VectorInt and asking the compiler to find T such that std::enable_if<std::is_same<T, VectorInt>::value, T>::type> happens to be VectorInt. This seems reasonable because intuitively enable_if is just the identity operator (for types) if the first argument is true. But the compiler has no special knowledge of enable_if. This is equivalent to saying: find T such that Foo<T>::type is Bar. The compiler has no way to do this shy of instantiating Foo for every single T, which is not possible.
We want to use enable_if, but not in a way that disables deduction. The best way to use enable_if is typically in a defaulted template parameter:
template<typename T, typename U = typename std::enable_if<std::is_same<T, VectorInt>::value>::type >
void serialize(T& vect) {
std::cout << vect.x << std::endl;
}
U isn't used for anything, but when serialize is passed a VectorInt, it will now deduce T from the passed argument, and then it will deduce U which has a default. However, if the enable_if argument is false then U will not correspond to any type, and the instantiation is ill-formed: classic SFINAE.
This answer is already pretty long, but enable_if itself is a reasonably deep topic; the form given above works here but doesn't work for disjoint sets of overloads. I'd suggest reading more about ADL, template argument deduction, SFINAE, and enable_if, outside of just SO (blog posts, Cppcon youtube videos, etc).

How does one pass "non trivially copyable objects" into a varargs function in GCC

I have a custom logger that uses a logger->logf(format, ...) style varargs method for logging. I have object handles that are wrappers around pointers. I have a special format specifier to print the objects ( with a toString() method like in Java)
The "handles" are not "trivially copyable" as they can be constructed from a number of input types, and have converter-cast operators that return the pointer to the contained object type. ( similar to ComPtr<> )
IN windows C++ I can just pass the handle in and the varags method sees the pointer. GCC considers this an error now. The handle is "sizeof(void *)"
Is there a way to get GCC to allow this on a varags method?
Is there a way to specify a special operator xx () method to be passed into a varargs method?
I have a rather large library with a lot of log lines in it and redoing all of them with operator + or operator << would be an intense chore.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Well if does look like the Variadic template is what I need to use but I have yet to figure out how to make it simple an elegant.
The essence of an algorithm would be
place object or buffer on stack (ideally based on the number of arguments)
add all the arguments to the object.
on the last argument add it to the object, as well and process the arguments.
The "recursive" nature of a variadic template makes a nice way to do this a bit to figure out.
#
Ok I bit the bullet and rewrote the formatter part to use variadic templates. It did take 3 days. Basically it involves having an "Arg" class that has a union of all the primitive types and a "type" field set by the constructor overload for each type.
Then a variadic template to "load a list" of args which is passed to the formatters equivalent of "vsprintf". Great as there is enough information to be runtime type safe. The quastion now is HOW much code bloat is there with the template expansion. As all they do is cast and the "Arg" is a fixed size and it's constructor just loads two fields, type and value. Will GCC and MSC nicely optimize all of it out so there aren't 2 ^ maxArgs full expansions of the variadic templates.
template <typename... Args>
int writef(const wchar_t *fmt, ...) {
FormatfArglist<sizeof...(Args)> arglist;
FormatfArgBase::addArgs(arglist.args(), args...);
return(vwritef(fmt, arglist));
}
template <typename First, typename... Rest>
static void FormatfArgBase::addArgs(Arg *arglist,
const First &first, const Rest &... rest) {
setArg(arglist,Arg(first));
if(sizeof... (Rest) > 0) {
addArgs(++arglist, rest...); // recursive call using pack expansion syntax
}
}
Seems as the C++ guys pile on restrictions on the old C ellipsis one really has to use Variadic templates to get full functionality.
So I bit the bullet and rewrote the formatter part to use variadic templates. It did take 3 days. Basically it involves having an "Arg" class that has a union of all the primitive types and a "type" field set by the constructor overload for each type.
Then a variadic template to "load a list" of args which is passed to the formatters equivalent of "vsprintf". Great as there is enough information to be runtime type safe. The question now is HOW much code bloat is there with the template expansion. As all they do is cast and the "Arg" is a fixed size and it's constructor just loads two fields, type and value. Will GCC and MSC nicely optimize all of it out so there aren't 2 ^ maxArgs full expansions of the variadic templates?
// This is in a "TextWriter" class
template <typename... Args>
int writef(const wchar_t *fmt, ...) {
FormatfArglist<sizeof...(Args)> arglist;
FormatfArgBase::addArgs(arglist.args(), args...);
return(vwritef(fmt, arglist));
}
template <typename First, typename... Rest>
static void FormatfArgBase::addArgs(Arg *arglist,
const First &first, const Rest &... rest) {
setArg(arglist,Arg(first));
if(sizeof... (Rest) > 0) {
addArgs(++arglist, rest...); // recursive call using pack expansion syntax
}
}
I am not sure why it works with Microsoft compiler. The standard clearly indicates, that
Only arithmetic, enumeration, pointer, pointer to member, and class
type arguments are allowed.
(http://en.cppreference.com/w/cpp/language/variadic_arguments).
For your particular case, I suggest you use variadic template function as an intermediate step to convert those values to pointers, and than call your Log function (which I imagine can't be template itself).

Order of function definition during template instantiation

I have trouble understanding the order of template instantiation. It seems that the compiler does not consider a function if it is defined "too late." The following steps illustrates the main ideas of the code below:
The framework should provide a free function convert<From, To> if it can find a working overload for the function generate.
The function to<T> is a shortcut for convert<From,To> and should only work if convert<From,To> is valid.
Users should be able to provide an overload of generate and be able to use to and convert.
The corresponding code:
#include <string>
#include <utility>
#include <iostream>
// If I move the code down below at [*] to this location, everything works as
// expected.
// ------------- Framework Code -------------
// Anything that can be generated can also be converted to a string.
template <typename From>
auto convert(From const& from, std::string& to)
-> decltype(
generate(std::declval<std::back_insert_iterator<std::string>&>(), from)
)
{
to.clear();
auto i = std::back_inserter(to);
return generate(i, from);
}
// Similar to convert, except that it directly returns the requested type.
template <typename To, typename From>
auto to(From const& f) -> decltype(convert(f, std::declval<To&>()), To())
{
To t;
if (! convert(f, t))
throw std::invalid_argument("invalid conversion");
return t;
}
// ------------- User Code -------------
// [*] Support arithmetic types.
template <typename Iterator, typename T>
auto generate(Iterator& out, T i)
-> typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
{
// Note: I merely use std::to_string for illustration purposes here.
auto str = std::to_string(i);
out = std::copy(str.begin(), str.end(), out);
return true;
}
int main()
{
uint16_t s = 16;
std::cout << to<std::string>(s) << std::endl;
return 0;
}
The problem in the following code is that it only works if the function generate appears before the definition of convert and to. How can I work around this problem?
Maybe my mental model is wrong here, but I thought the template when the compiler sees to<std::string>(uint16_t), it starts going backwards to and instantiate as needed. Any guidance would be appreciated.
The compiler does not know of the existence of generate by the time it sees the definition of convert and to, as you have already guessed yourself. Contrary to what you thought, it doest not though sort of put the definitions of convert and to "on hold" until it sees what generate is. To workaround this problem you need to forward declare generate, what can be done using the following construction:
template <typename Iterator, typename T>
auto generate(Iterator& out, T i)
-> typename std::enable_if<std::is_arithmetic<T>::value, bool>::type;
This should appear right before the definition of convert, so that the compiler knows generate actually exists and also is a function by the time it compiles convert and to. This way the compiler can check the syntax and guarantee it is a valid call to generate, even before it knows what generate actually does, since all it needs to do at this point is check if the types of the arguments as well as of the return value match, according to the rules defined by the language standard.
By doing this, you naturally enforce a specific type signature for generate (remember the compiler is required to check the types when it compiles convert and to!). If you don't want to do that, and you probably don't, then the best approach is to expect a further template argument to convert and to likewise, which you expect to be callable, that is, which you can use as in a function call:
template <typename From, typename Generator>
auto convert(From const& from, std::string& to, Generator generate)
-> decltype(
generate(std::declval<std::back_insert_iterator<std::string>&>(), from)
)
{
to.clear();
auto i = std::back_inserter(to);
return generate(i, from);
}
These kind of objects are commonly known as callable objects.
The drawback to this approach is that because c++ unfortunately does not support concepts yet, you can't do much to enforce the requirements the callable object generate should attend to. Nonetheless, this approach is what the std library successfully uses for its algorithms.
The advantage of this approach is that it can be very flexible, for any possible callable object, which minimally attends to the type requirements, can be used. That includes free functions, function objects, member functions through binding, among others. Not to mention the user is absolutely free to choose the name she wants for her callable object instead of being forced to use generate, as your initial idea would require if it were valid c++.
Now to call this modified version of convert using the free function generateyou defined, you would do that:
to<std::string>(s, generate<std::back_insert_iterator<std::string>, uint16_t>);
That isn't very nice, because since you must explicitly state the template arguments, this approach fails to take full advantage of the fact generate is a template function. Fortunately this inconvenience can be overcome by the use of function objects, like the following for instance:
struct Generator
{
template <typename Iterator, typename T>
auto operator()(Iterator& out, T i)
-> typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
{
// Note: I merely use std::to_string for illustration purposes here.
auto str = std::to_string(i);
out = std::copy(str.begin(), str.end(), out);
return true;
}
};
The previous call would become simply
to<std::string>(s, Generator());
taking full advantage of its tamplate nature.
At any rate, if I got the idea correctly, this part of the code is of responsability of the user, so she, as she deserves, have full autonomy to decide which way she prefers.

Is there a way to use SFINAE to determine if a call to a templated function would fail due to the types provided?

I have a templated class that I am using to provide a method that will use boost::lexical_cast to cast its std::string parameters to the type specified in the template, only if the lexical cast is possible. Currently to check if it's possible I'm simply checking to see if operator>> is defined for the type in question. Here is a contrived example that basically illustrates what I'm doing:
template <typename ArgType, class Enable = void>
MyHelperClass
{
void Foo (ArgType arg&, std::string strArg) { } // not castable; do nothing
};
template <typename ArgType>
MyHelperClass<ArgType, boost::enable_if<boost::has_right_shift<std::istream, ArgType> >::type>
{
void Foo (ArgType arg&, std::string strArg) {
arg = boost::lexical_cast<ArgType>(strArg); // cast string arg to ArgType
}
};
So far this works fine for my code: all of the types that would fail a lexical cast end up with the first version and all others end up with the second, at least for the types my code is using this on. What I'm worried about is that I'm basically making the assumption that as long as the target type is InputStreamable then lexical_cast will not fail. The boost documentation for lexical_cast outlines some other requirements, which I should probably be checking as well but rather than creating a complex enable-if and use mpl::and_ to string together a bunch of these conditions, I was wondering: is there a way to use SFINAE to just test directly whether that call to lexical_cast would fail for the types given, and match the specialized template only if it wouldn't fail?
I've only ever seen examples for testing the existence of a function or operator, but never to test if a call to a templated function with a given type would produce an error.
I'm afraid not. Because lexical_cast is defined for all T, SFINAE won't help you. The fact that the body of lexical_cast() will fail to compile for certain types does not cause a substitution failure. The best you can do is to try to predict the conditions that will cause the body to fail, as you have already been doing.

Use static_assert to check types passed to macro

I unfortunately have several macros left over from the original version of my library that employed some pretty crazy C. In particular, I have a series of macros that expect certain types to be passed to them. Is it possible to do something along the lines of:
static_assert(decltype(retval) == bool);
And how? Are there any clever alternatives?
Yes I'm aware macros are bad. I'm aware C++ is not C, etc.
Update0
Here is some related code, and the source file. Suggestions are welcome. The original question remains the same.
I found this to be the cleanest, using #UncleBens suggestion:
#include <type_traits>
static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
Disclaimer: This is a bad answer, there are definitely far better solutions. Just an example :)
It is bound to be already implemented, but it's trivial to implement yourself;
template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //
template <class T1, class T2>
AssertHasType(T2)
{
CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}
To be used like this:
AssertHasType<bool>(retval);
Alternative (suggested by GMan):
template <class T1, class T2> struct SameType
{
enum{value = false};
}
template <class T> struct SameType<T,T>
{
enum{value = true};
};
To be used like
static_assert(SameType<decltype(retval), bool>::value);
It appears you need decltype because you've got an expression, but want to verify a type. There are already enough ways to do that now (C++03). For instance, to check a bool
inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)
// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
If you DO care about the const and volatile qualifiers, and want to ensure the const and volatile parts of the types also exactly match the type you are comparing against, do like #Matt Joiner says:
#include <type_traits>
static_assert(std::is_same<decltype(my_variable), uint64_t>::value,
"type must be `uint64_t`");
I you do NOT care about const, however, and want to simply ensure the type is a certain type without regard for const, do the following instead. Note that std::remove_const<>::type is required here:
static_assert(std::is_same<std::remove_const<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `const uint64_t`");
The same goes for volatile. In case you don't care about the volatile part of the type either, you can ignore it with std::remove_volatile<>::type:
static_assert(std::is_same<std::remove_volatile<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `volatile uint64_t`");
If you don't care about const OR volatile, you can remove them both with std::remove_cv<>::type:
static_assert(std::is_same<std::remove_cv<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `const uint64_t` OR `volatile uint64_t` OR `volatile const uint64_t`");
Note also that as of C++17 you can do:
std::remove_cv_t<decltype(my_variable)> in place of std::remove_cv<decltype(my_variable)>::type, and:
std::is_same_v<some_type, another_type> in place of std::is_same<some_type, another_type>::value.
References:
Use static_assert to check types passed to macro
https://en.cppreference.com/w/cpp/types/is_same
https://en.cppreference.com/w/cpp/language/decltype
https://en.cppreference.com/w/cpp/header/type_traits
https://en.cppreference.com/w/cpp/types/remove_cv - std::remove_cv<>, std::remove_const<>, std::remove_volatile<>
Related:
[another answer of mine where I use the above static_assert tricks] How to make span of spans
Static assert in C [my own answer]
How to use static assert in C to check the types of parameters passed to a macro [my own question]
Typechecking macro arguments in C
*****C++ Limit template type to numbers
Most macros can be replaced with inline functions and/or templates. As a case in point, the overly clever argument-size-checking Posix isnan macro is a template in C++0x. Oh,bad example, but you get the idea.
The main exceptions to that rule are macros that essentially implement higher level language features. For example, smarter exception handling, or covariance, or a parameterized set of declarations.
In some cases the macros that can't be reasonable expressed as inline functions or templates, can be replaced with a smarter kind of preprocessing, namely code generation. Then you have a script somewhere that generates the necessary code. For example, it's possible to do options classes in pure C++ with macros and templates, but it's hairy, and as an easier-to-grok and perhaps more maintainable alternative one might use a script that generates the requisite classes, at the cost of extra build steps and dealing with multiple languages.
Cheers & hth.,