cereal/assets/doxygen/group__Utility.html
2022-02-27 19:48:38 -08:00

353 lines
24 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>cereal: Utility Functionality</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">cereal
</div>
<div id="projectbrief">A C++11 library for serialization</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#define-members">Macros</a> &#124;
<a href="#func-members">Functions</a> </div>
<div class="headertitle">
<div class="title">Utility Functionality</div> </div>
</div><!--header-->
<div class="contents">
<p>Name-value pairs, binary data wrappers, exceptions, and other utility functions.
<a href="#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structcereal_1_1RapidJSONException.html">cereal::RapidJSONException</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">An exception thrown when rapidjson fails an internal assertion. <a href="structcereal_1_1RapidJSONException.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structcereal_1_1Exception.html">cereal::Exception</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">An exception class thrown when things go wrong at runtime. <a href="structcereal_1_1Exception.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
Macros</h2></td></tr>
<tr class="memitem:ga78892c2ccfac7a5454639ca121e84439"><td class="memItemLeft" align="right" valign="top"><a id="ga78892c2ccfac7a5454639ca121e84439"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__Utility.html#ga78892c2ccfac7a5454639ca121e84439">CEREAL_NVP</a>(T)&#160;&#160;&#160;::cereal::make_nvp(#T, T)</td></tr>
<tr class="memdesc:ga78892c2ccfac7a5454639ca121e84439"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates a name value pair for the variable T with the same name as the variable. <br /></td></tr>
<tr class="separator:ga78892c2ccfac7a5454639ca121e84439"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gabea833652252591a51f75cb9ce31f44a"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__Utility.html#gabea833652252591a51f75cb9ce31f44a">CEREAL_CLASS_VERSION</a>(TYPE, VERSION_NUMBER)</td></tr>
<tr class="memdesc:gabea833652252591a51f75cb9ce31f44a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Defines a class version for some type. <a href="group__Utility.html#gabea833652252591a51f75cb9ce31f44a">More...</a><br /></td></tr>
<tr class="separator:gabea833652252591a51f75cb9ce31f44a"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:ga5bfb9090edc7c741335fba284e462a49"><td class="memTemplParams" colspan="2"><a id="ga5bfb9090edc7c741335fba284e462a49"></a>
template&lt;class T &gt; </td></tr>
<tr class="memitem:ga5bfb9090edc7c741335fba284e462a49"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="classcereal_1_1NameValuePair.html">NameValuePair</a>&lt; T &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="group__Utility.html#ga5bfb9090edc7c741335fba284e462a49">make_nvp</a> (std::string const &amp;name, T &amp;&amp;value)</td></tr>
<tr class="memdesc:ga5bfb9090edc7c741335fba284e462a49"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates a name value pair. <br /></td></tr>
<tr class="separator:ga5bfb9090edc7c741335fba284e462a49"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga4ae230f9f8c3d979df8daa95ef6cbcdc"><td class="memTemplParams" colspan="2"><a id="ga4ae230f9f8c3d979df8daa95ef6cbcdc"></a>
template&lt;class T &gt; </td></tr>
<tr class="memitem:ga4ae230f9f8c3d979df8daa95ef6cbcdc"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="classcereal_1_1NameValuePair.html">NameValuePair</a>&lt; T &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="group__Utility.html#ga4ae230f9f8c3d979df8daa95ef6cbcdc">make_nvp</a> (const char *name, T &amp;&amp;value)</td></tr>
<tr class="memdesc:ga4ae230f9f8c3d979df8daa95ef6cbcdc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates a name value pair. <br /></td></tr>
<tr class="separator:ga4ae230f9f8c3d979df8daa95ef6cbcdc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga593d161603775672f91ab448ef65083e"><td class="memTemplParams" colspan="2">template&lt;class T &gt; </td></tr>
<tr class="memitem:ga593d161603775672f91ab448ef65083e"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="structcereal_1_1BinaryData.html">BinaryData</a>&lt; T &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="group__Utility.html#ga593d161603775672f91ab448ef65083e">binary_data</a> (T &amp;&amp;<a class="el" href="structcereal_1_1BinaryData.html#a0bac12b9a4e870dfb89a73d6731f9109">data</a>, size_t <a class="el" href="structcereal_1_1BinaryData.html#a6c5b15fee4187ac9d948081a3ea9cfe3">size</a>)</td></tr>
<tr class="memdesc:ga593d161603775672f91ab448ef65083e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Convenience function to create binary data for both const and non const pointers. <a href="group__Utility.html#ga593d161603775672f91ab448ef65083e">More...</a><br /></td></tr>
<tr class="separator:ga593d161603775672f91ab448ef65083e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga4d4b256b14671c8270d06f40e4c4a077"><td class="memTemplParams" colspan="2">template&lt;class T &gt; </td></tr>
<tr class="memitem:ga4d4b256b14671c8270d06f40e4c4a077"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="classcereal_1_1SizeTag.html">SizeTag</a>&lt; T &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="group__Utility.html#ga4d4b256b14671c8270d06f40e4c4a077">make_size_tag</a> (T &amp;&amp;sz)</td></tr>
<tr class="memdesc:ga4d4b256b14671c8270d06f40e4c4a077"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates a size tag from some variable. <a href="group__Utility.html#ga4d4b256b14671c8270d06f40e4c4a077">More...</a><br /></td></tr>
<tr class="separator:ga4d4b256b14671c8270d06f40e4c4a077"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafc913c738d15fc5dd7f4a7a20edb5225"><td class="memTemplParams" colspan="2">template&lt;class T &gt; </td></tr>
<tr class="memitem:gafc913c738d15fc5dd7f4a7a20edb5225"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="classcereal_1_1DeferredData.html">DeferredData</a>&lt; T &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="group__Utility.html#gafc913c738d15fc5dd7f4a7a20edb5225">defer</a> (T &amp;&amp;value)</td></tr>
<tr class="memdesc:gafc913c738d15fc5dd7f4a7a20edb5225"><td class="mdescLeft">&#160;</td><td class="mdescRight">Marks data for deferred serialization. <a href="group__Utility.html#gafc913c738d15fc5dd7f4a7a20edb5225">More...</a><br /></td></tr>
<tr class="separator:gafc913c738d15fc5dd7f4a7a20edb5225"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<p>Name-value pairs, binary data wrappers, exceptions, and other utility functions. </p>
<h2 class="groupheader">Macro Definition Documentation</h2>
<a id="gabea833652252591a51f75cb9ce31f44a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gabea833652252591a51f75cb9ce31f44a">&#9670;&nbsp;</a></span>CEREAL_CLASS_VERSION</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define CEREAL_CLASS_VERSION</td>
<td>(</td>
<td class="paramtype">&#160;</td>
<td class="paramname">TYPE, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">&#160;</td>
<td class="paramname">VERSION_NUMBER&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<b>Value:</b><div class="fragment"><div class="line"> <span class="keyword">namespace </span>cereal { <span class="keyword">namespace </span>detail { \</div>
<div class="line"> template &lt;&gt; <span class="keyword">struct </span>Version&lt;TYPE&gt; \</div>
<div class="line"> { \</div>
<div class="line"> static <span class="keyword">const</span> std::uint32_t version; \</div>
<div class="line"> static std::uint32_t registerVersion() \</div>
<div class="line"> { \</div>
<div class="line"> ::cereal::detail::StaticObject&lt;Versions&gt;::getInstance().mapping.emplace( \</div>
<div class="line"> std::type_index(<span class="keyword">typeid</span>(TYPE)).hash_code(), VERSION_NUMBER ); \</div>
<div class="line"> return VERSION_NUMBER; \</div>
<div class="line"> } \</div>
<div class="line"> CEREAL_UNUSED_FUNCTION \</div>
<div class="line"> }; <span class="comment">/* end Version */</span> \</div>
<div class="line"> const std::uint32_t Version&lt;TYPE&gt;::version = \</div>
<div class="line"> Version&lt;TYPE&gt;::registerVersion(); \</div>
<div class="line"> } }</div>
</div><!-- fragment -->
<p>Defines a class version for some type. </p>
<p>Versioning information is optional and adds some small amount of overhead to serialization. This overhead will occur both in terms of space in the archive (the version information for each class will be stored exactly once) as well as runtime (versioned serialization functions must check to see if they need to load or store version information).</p>
<p>Versioning is useful if you plan on fundamentally changing the way some type is serialized in the future. Versioned serialization functions cannot be used to load non-versioned data.</p>
<p>By default, all types have an assumed version value of zero. By using this macro, you may change the version number associated with some type. cereal will then use this value as a second parameter to your serialization functions.</p>
<p>The interface for the serialization functions is nearly identical to non-versioned serialization with the addition of a second parameter, const std::uint32_t version, which will be supplied with the correct version number. Serializing the version number on a save happens automatically.</p>
<p>Versioning cannot be mixed with non-versioned serialization functions. Having both types will result result in a compile time error. Data serialized without versioning cannot be loaded by a serialization function with added versioning support.</p>
<p>Example interface for versioning on a non-member serialize function:</p>
<div class="fragment"><div class="line"><a class="code" href="group__Utility.html#gabea833652252591a51f75cb9ce31f44a">CEREAL_CLASS_VERSION</a>( Mytype, 77 ); <span class="comment">// register class version</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span> &lt;<span class="keyword">class</span> Archive&gt;</div>
<div class="line"><span class="keywordtype">void</span> <a class="code" href="functional_8hpp.html#a02f9cfc9a4055c8a49eb050b02cd3357">serialize</a>( Archive &amp; ar, Mytype &amp; t, <span class="keyword">const</span> std::uint32_t version )</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// When performing a load, the version associated with the class</span></div>
<div class="line"> <span class="comment">// is whatever it was when that data was originally serialized</span></div>
<div class="line"> <span class="comment">//</span></div>
<div class="line"> <span class="comment">// When we save, we&#39;ll use the version that is defined in the macro</span></div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span>( version &gt;= some_number )</div>
<div class="line"> <span class="comment">// do this</span></div>
<div class="line"> <span class="keywordflow">else</span></div>
<div class="line"> <span class="comment">// do that</span></div>
<div class="line">}</div>
</div><!-- fragment --><p>Interfaces for other forms of serialization functions is similar. This macro should be placed at global scope. On C++17, define the StaticObject as inline to merge the definitions across TUs This prevents multiple definition errors when this macro appears in a header file included in multiple TUs. </p>
</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="ga593d161603775672f91ab448ef65083e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga593d161603775672f91ab448ef65083e">&#9670;&nbsp;</a></span>binary_data()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T &gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="structcereal_1_1BinaryData.html">BinaryData</a>&lt; T &gt; binary_data </td>
<td>(</td>
<td class="paramtype">T &amp;&amp;&#160;</td>
<td class="paramname"><em>data</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Convenience function to create binary data for both const and non const pointers. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">data</td><td>Pointer to beginning of the data </td></tr>
<tr><td class="paramname">size</td><td>The size in bytes of the data </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="gafc913c738d15fc5dd7f4a7a20edb5225"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gafc913c738d15fc5dd7f4a7a20edb5225">&#9670;&nbsp;</a></span>defer()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T &gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classcereal_1_1DeferredData.html">DeferredData</a>&lt; T &gt; defer </td>
<td>(</td>
<td class="paramtype">T &amp;&amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Marks data for deferred serialization. </p>
<p>cereal performs a recursive depth-first traversal of data it serializes. When serializing smart pointers to large, nested, or cyclical data structures, it is possible to encounter a stack overflow from excessive recursion when following a chain of pointers.</p>
<p>Deferment can help in these situations if the data can be serialized separately from the pointers used to traverse the structure. For example, a graph structure can have its nodes serialized before its edges:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>MyEdge</div>
<div class="line">{</div>
<div class="line"> std::shared_ptr&lt;MyNode&gt; connection;</div>
<div class="line"> <span class="keywordtype">int</span> some_value;</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">class</span> Archive&gt;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code" href="functional_8hpp.html#a02f9cfc9a4055c8a49eb050b02cd3357">serialize</a>(Archive &amp; archive)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// when we serialize an edge, we&#39;ll defer serializing the associated node</span></div>
<div class="line"> archive( cereal::defer( connection ),</div>
<div class="line"> some_value );</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>MyGraphStructure</div>
<div class="line">{</div>
<div class="line"> std::vector&lt;MyEdge&gt; edges;</div>
<div class="line"> std::vector&lt;MyNodes&gt; nodes;</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">class</span> Archive&gt;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code" href="functional_8hpp.html#a02f9cfc9a4055c8a49eb050b02cd3357">serialize</a>(Archive &amp; archive)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// because of the deferment, we ensure all nodes are fully serialized</span></div>
<div class="line"> <span class="comment">// before any connection pointers to those nodes are serialized</span></div>
<div class="line"> archive( edges, nodes );</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// we have to explicitly inform the archive when it is safe to serialize</span></div>
<div class="line"> <span class="comment">// the deferred data</span></div>
<div class="line"> archive.serializeDeferments();</div>
<div class="line"> }</div>
<div class="line">};</div>
</div><!-- fragment -->
</div>
</div>
<a id="ga4d4b256b14671c8270d06f40e4c4a077"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga4d4b256b14671c8270d06f40e4c4a077">&#9670;&nbsp;</a></span>make_size_tag()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T &gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classcereal_1_1SizeTag.html">SizeTag</a>&lt; T &gt; make_size_tag </td>
<td>(</td>
<td class="paramtype">T &amp;&amp;&#160;</td>
<td class="paramname"><em>sz</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Creates a size tag from some variable. </p>
<p>Will normally be used to serialize size (e.g. size()) information for variable size containers. If you have a variable sized container, the very first thing it serializes should be its size, wrapped in a <a class="el" href="classcereal_1_1SizeTag.html" title="A wrapper around size metadata.">SizeTag</a>. </p>
</div>
</div>
</div><!-- contents -->
<div class="ttc" id="agroup__Utility_html_gabea833652252591a51f75cb9ce31f44a"><div class="ttname"><a href="group__Utility.html#gabea833652252591a51f75cb9ce31f44a">CEREAL_CLASS_VERSION</a></div><div class="ttdeci">#define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER)</div><div class="ttdoc">Defines a class version for some type.</div><div class="ttdef"><b>Definition:</b> cereal.hpp:281</div></div>
<div class="ttc" id="afunctional_8hpp_html_a02f9cfc9a4055c8a49eb050b02cd3357"><div class="ttname"><a href="functional_8hpp.html#a02f9cfc9a4055c8a49eb050b02cd3357">cereal::serialize</a></div><div class="ttdeci">void serialize(Archive &amp;, std::less&lt; T &gt; &amp;)</div><div class="ttdoc">Saving for std::less.</div><div class="ttdef"><b>Definition:</b> functional.hpp:39</div></div>
<!-- HTML footer for doxygen 1.8.3.1-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Sun Feb 27 2022 19:46:46 for cereal by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.17
</small></address>
<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','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-42360142-1', 'uscilab.github.io');
ga('send', 'pageview');
</script>
</body>
</html>