-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnamed-tuple.html
More file actions
236 lines (167 loc) · 9.18 KB
/
named-tuple.html
File metadata and controls
236 lines (167 loc) · 9.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<!DOCTYPE html>
<HTML>
<HEAD>
<title>nuple: a Named Tuple - Alexandr Poltavsky, software developer</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="css/common.css" />
<link rel="stylesheet" href="highlight/styles/hybrid.css">
</HEAD>
<BODY>
<div id="wrap">
<!-- header part -->
<div id="header">
<a href="/color-throne.html"><img class="ad" src="images/color-throne-logo-promo.png" title="Color Throne Game"/></a>
<div class="avatar">
<a href="/">
<img class="avatar" width="160" src="images/alexandr-poltavsky-avatar.jpeg" title="Alexandr Poltavsky" align="left"/>
</a>
</div>
<div class="text">
<span class="bio">
Alexandr Poltavsky <br/>
Software Developer <br/>
Location: Russia, Moscow <br/>
<span class="email">
<a href="mailto:poltavsky.alexandr@gmail.com">poltavsky.alexandr@gmail.com</a><br/>
</span>
</span>
<div class="break"></div>
<span class="links">
<a href="/">Blog</a>
<a href="https://github.com/alexpolt/">Github</a>
<a href="https://www.shadertoy.com/user/alexpolt">Shadertoy</a>
<a href="https://twitter.com/poltavsky_alex">Twitter</a>
</span>
</div>
</div>
<div id="content" style="clear: left">
<!-- here goes the main content -->
<div id="main-menu">
<a id="main-menu-0" href="index.html">Programming</a>
<a id="main-menu-1" href="index-gfx.html">Graphics</a>
<a id="main-menu-2" href="index-off.html">Off-topic</a>
</div>
<h2>nuple: a Named Tuple</h2>
<p>While browsing the Internets I came upon this <a href="http://vitiy.info/named-tuple-for-cplusplus/" title="Named tuple for C++">blog post</a> by <a href="http://twitter.com/VictorLaskin" title="Victor Laskin Twitter">Victor Laskin</a>.
In there he describes an implementation of a named tuple in C++. It just so happened that some
time ago I was writing about useful properties of string interning in C++. I quickly realized
that another good use of it is to implement a named tuple which I called <strong>nuple</strong> - a named
tuple. By the way, you should check up Victor's <a href="http://vitiy.info/" title="Victor Laskin's Blog">blog</a> if you're a fan of functional
programming and C++.</p>
<p>So, the implementation turned out to be pretty simple. The usage is like this:</p>
<pre><code>using nameid_t = nuple< $("name"), char const*, $("id"), int >;
</code></pre>
<p>The dollar sign is <a href="intern.html" title="Useful Properties of String Interning in C++">string interning</a> which turns a string literal into a type. All we
have to do is to sort this parameter type list into a names list and a type list. The type list
is then passed to <a href="https://github.com/alexpolt/luple/">luple</a> which is a lightweight (source code I mean) tuple I created for
the <a href="type-loophole.html" title="The C++ Type Loophole (C++14)">C++ type loophole</a>. The <a href="https://github.com/alexpolt/luple/">source code</a> (GitHub) is short and easy to read
(header is <strong>nuple.h</strong>).</p>
<p>So, here's an example of using it:</p>
<pre><code>nameid_t n[] = { {"alex", 1}, {"ivan", 2} };
for( auto& v : n )
printf( "name: %s, id: %d\n", get<$("name")>(v), get<$("id")>(v) );
</code></pre>
<p>Because <strong>nuple</strong> inherits from <strong>luple</strong> (I'm not good at terminology) we can use all other
tuple-like methods:</p>
<pre><code>auto get_person(int i) { return nameid_t{"john", i}; }
auto p = get_person(3);
printf( "tuple size: %d\n", size(p) );
get<0>(p) = "irene";
get<int>(p) = 4;
printf( "name: %s, id: %d\n", get<$("name")>(p), get<$("id")>(p) );
</code></pre>
<p>See it in action <a href="https://goo.gl/zvo26z" title="luple Online Example at tio.run">online at tio.run</a> (also <a href="http://coliru.stacked-crooked.com/a/52984bf7d0b4db19" title="luple Online Example at Coliru">Coliru</a> or <a href="https://wandbox.org/permlink/ghbTSf5LwztoyCta" title="luple Online Example at Wandbox">Wandbox</a>).</p>
<p>Also a nuple-to-json <a href="https://goo.gl/c8ofW5" title="luple Online Example at tio.run">example at tio.run</a> (also <a href="http://coliru.stacked-crooked.com/a/8f2f84adae0cb751" title="luple Online Example at Coliru">Coliru</a> or <a href="https://wandbox.org/permlink/NBHrlq8UJ9kDf0KS" title="luple Online Example at Wandbox">Wandbox</a>).</p>
<p>There is no hacks. It's all valid C++ <a href="https://github.com/alexpolt/luple/">source code</a> (C++14) and can be safely used in
production code. There is a limit on string length of 10 characters (sort of arbitrary), you can
increase it by editing the $(...) macro in the intern.h header. Or #define N3599 to use the
<a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3599.html" title="Literal operator templates for strings">N3599</a> proposal (adds string literal template to the language) which GCC and Clang implement
as an extension. (Update: defined by default for GCC and Clang)</p>
<p><strong>Update</strong>. Added syntax like this:</p>
<pre><code>auto get_person( int id ) {
return as_nuple( $name("name"), "Victoria", $name("id"), id );
}
auto p = get_person( 5 );
std::cout << get<$("name")>( p );
</code></pre>
<p>Here macro $name(...) returns a value of an <a href="intern.html" title="Useful Properties of String Interning in C++">interned string</a> type ( $(...) gives a type ).</p>
<p>There is a Reddit <a href="https://www.reddit.com/r/cpp/comments/75wc6j/nuple_a_named_tuple/" title="nuple: a Named Tuple on Reddit">discussion</a>. Follow me on <a href="https://twitter.com/poltavsky_alex" title="Alexandr Poltavsky, Software Developer">Twitter</a> for updates about my new
articles (mostly programming and computer graphics). </p>
<script>
document.addEventListener( "DOMContentLoaded", function() {
if( /iPhone|iPad|iPod|Android|Windows Phone/i.test(navigator.userAgent) ) {
document.getElementById("wrap").classList.add("mobile");
}
} );
</script>
<script src="highlight/highlight.pack.js"></script>
<script>
//hljs.configure({languages: ["C++"]});
hljs.initHighlightingOnLoad();
</script>
<div id="disqus_comments"><a href="javascript: run_disqus()">read and write commentaries</a></div>
<div id="disqus_thread"></div>
<script>
/**
* RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
* LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables
*/
/*
var disqus_config = function () {
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
*/
function run_disqus() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = '//alexpolt-github-io.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
d.getElementById("disqus_comments").innerHTML = ""; // alexpolt
return undefined;
};
if( location.hash.indexOf("comment") != -1 ) run_disqus();
</script>
<!--noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments
powered by Disqus.</a></noscript-->
</div> <!-- end content -->
</div> <!-- end wrap -->
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-75341409-1', 'auto');
ga('send', 'pageview');
</script>
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function (d, w, c) {
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter43425229 = new Ya.Metrika({
id:43425229,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true
});
} catch(e) { }
});
var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = "https://mc.yandex.ru/metrika/watch.js";
if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }
})(document, window, "yandex_metrika_callbacks");
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/43425229" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</BODY>