Created
August 16, 2016 12:24
-
-
Save cppljevans/555ba34134a82c8a524d8c42702c9d28 to your computer and use it in GitHub Desktop.
illuminate create_window code in D0424R0.pdf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Purpose: | |
// Illustrate the workings of the create_window code found in attachment to: | |
/* | |
https://groups.google.com/a/isocpp.org/forum/?utm_medium=email&utm_source=footer#!msg/std-proposals/b1X597zMx9s/4fnQB6gBCwAJ | |
*/ | |
//Modifications: | |
// Renamed create_window to named_args and renamed many other | |
// types and variables to make them more generic or readable. | |
// Added several comments explaining purpose of various parts. | |
// Added extensive print statements to illustrate how code | |
// worked. | |
//========================= | |
#include <iostream> | |
template <char ...s> | |
struct argument | |
{ | |
using this_arg_name_t=argument<s...>; | |
template<typename ArgType> | |
using this_arg_name_val_t=std::pair<this_arg_name_t,ArgType>; | |
static std::string | |
this_name() | |
{ | |
static char const str[sizeof...(s)+1]={s...,'\0'}; | |
return str; | |
} | |
static std::string | |
this_type_name() | |
{ | |
std::string prefix("argument<"); | |
std::string suffix(">"); | |
return prefix+this_name()+suffix; | |
} | |
argument() | |
{ | |
std::cout | |
<<this_type_name()<<"::default CTOR" | |
<<"\n"; | |
} | |
/**@brief | |
* Used to generates *actual* arguments to a function. | |
*/ | |
template <typename ArgType> | |
this_arg_name_val_t<ArgType> | |
operator=(ArgType arg_value) | |
{ | |
std::cout | |
<<this_type_name()<<"::operator=(ArgType arg_value)" | |
<<":arg_value=" | |
<<arg_value | |
<<"\n"; | |
return {{}, arg_value}; | |
} | |
/**@brief | |
* Used in body of function to extract the desired value | |
* of an argument with name, this_arg_name_t::this_name(). | |
* This is used in combination with next auto operator() | |
* to linearly search the arguments in the body of a function | |
* to extract the desired argument values. | |
*/ | |
template | |
< typename ThisArgType | |
, typename ...TailArgNameVals | |
> | |
auto operator() | |
( this_arg_name_val_t<ThisArgType> a | |
, TailArgNameVals ... | |
) const | |
{ | |
std::cout | |
<<this_type_name() | |
<<"::operator()(this_arg_name_t<ThisArgType> a, TailArgNameVals...)const" | |
<<":a.second="<<a.second | |
<<"\n"; | |
return a.second; | |
} | |
/**@brief | |
* Used in body of function to extract the desired value | |
* of an argument with name, this_arg_name_t::this_name(). | |
* In this call, HeadArgNameVal does *not* match | |
* this_arg_name_val_t<ThisArgType> for any ThisArgType; hence, | |
* the TailArgNameVals are searched for a match in the | |
* recursive call. | |
* This is used in combination with previous auto operator() | |
* to linearly search the arguments in the body of a function | |
* to extract the desired argument values. | |
*/ | |
template | |
< typename HeadArgName | |
//instance of argument<t...> but where t... != s... | |
, typename HeadArgType | |
, typename ...TailArgNameVals | |
> | |
auto operator() | |
( std::pair<HeadArgName,HeadArgType> | |
, TailArgNameVals ...args | |
) const | |
{ | |
unsigned const tail_size=sizeof...(TailArgNameVals); | |
std::cout | |
<<this_type_name() | |
<<"::operator()(HeadArgNameVal, TailArgNameVals...)const" | |
<<":head_name="<<HeadArgName::this_name() | |
<<":tail_size="<<tail_size | |
<<"\n"; | |
static_assert(tail_size != 0, "missing argument"); | |
return (*this)(args...); | |
} | |
}; | |
template <typename CharT, CharT ...s> | |
argument<s...> operator"" _arg() | |
{ | |
std::cout<<argument<s...>::this_type_name()<<" operator \"\" _arg()\n"; | |
return {}; | |
} | |
template <typename ...NameVals> | |
void named_args(NameVals ...name_vals) | |
{ | |
std::cout<<"named_args(NameVals... name_vals)\n"; | |
int var0 = "var0"_arg(name_vals...); | |
std::cout<<"var0="<<var0<<"\n"; | |
int var1 = "var1"_arg(name_vals...); | |
std::cout<<"var1="<<var1<<"\n"; | |
int var2 = "var2"_arg(name_vals...); | |
std::cout<<"var2="<<var2<<"\n"; | |
} | |
int main() { | |
named_args | |
( "var0"_arg = 0 | |
, "var2"_arg = 2 | |
, "var1"_arg = 1 | |
); | |
return 0; | |
} | |
//invocation&output: | |
/* | |
/tmp/build/clangxx3_8_pkg/clang/p0424ro/p0424r0_test.exe | |
argument<var0> operator "" _arg() | |
argument<var0>::default CTOR | |
argument<var0>::operator=(ArgType arg_value):arg_value=0 | |
argument<var0>::default CTOR | |
argument<var2> operator "" _arg() | |
argument<var2>::default CTOR | |
argument<var2>::operator=(ArgType arg_value):arg_value=2 | |
argument<var2>::default CTOR | |
argument<var1> operator "" _arg() | |
argument<var1>::default CTOR | |
argument<var1>::operator=(ArgType arg_value):arg_value=1 | |
argument<var1>::default CTOR | |
named_args(NameVals... name_vals) | |
argument<var0> operator "" _arg() | |
argument<var0>::default CTOR | |
argument<var0>::operator()(this_arg_name_t<ThisArgType> a, TailArgNameVals...)const:a.second=0 | |
var0=0 | |
argument<var1> operator "" _arg() | |
argument<var1>::default CTOR | |
argument<var1>::operator()(HeadArgNameVal, TailArgNameVals...)const:head_name=var0:tail_size=2 | |
argument<var1>::operator()(HeadArgNameVal, TailArgNameVals...)const:head_name=var2:tail_size=1 | |
argument<var1>::operator()(this_arg_name_t<ThisArgType> a, TailArgNameVals...)const:a.second=1 | |
var1=1 | |
argument<var2> operator "" _arg() | |
argument<var2>::default CTOR | |
argument<var2>::operator()(HeadArgNameVal, TailArgNameVals...)const:head_name=var0:tail_size=2 | |
argument<var2>::operator()(this_arg_name_t<ThisArgType> a, TailArgNameVals...)const:a.second=2 | |
var2=2 | |
Compilation finished at Tue Aug 16 06:56:03 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment