Skip to content

Instantly share code, notes, and snippets.

@cppljevans
Created August 16, 2016 12:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cppljevans/555ba34134a82c8a524d8c42702c9d28 to your computer and use it in GitHub Desktop.
Save cppljevans/555ba34134a82c8a524d8c42702c9d28 to your computer and use it in GitHub Desktop.
illuminate create_window code in D0424R0.pdf
//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