OTL 4.0, otl_read_row / otl_write_row template functions

otl_read_row / otl_write_row functions exist as variadic templates (for an arbitrary number of parameters), and as nonvariadic templates (for a number of parameters in the range of [1..15]). The variadic templates are supported under #define OTL_CPP_11_ON (or any higher levels of C++XX standard support, for example under  OTL_CPP_14_ON, or OTL_CPP_17_ON), and are enabled for C++ compilers that support variadic template functions.  The functions are enabled for g++ 4.7 and higher under #define OTL_CPP_11_ON, or CLANG++ 3.4 and higher (typically when the following command line options are enabled: -DOTL_CPP_11_ON -std=c++11), and automatically for Visual C++ 2013. Visual C++ 2015 requires #define OTL_CPP_11_ON or OTL_CPP_14_ON. The nonvariadic templates are supported by any C++ compilers.

Here are the signatures of the variadic template functions:

template<typename OTLStream,typename Arg1,typename...Args> 
void otl_read_row(OTLStream& s,Arg1& arg1,Args&...args);

template<typename OTLStream,typename Arg1, typename...Args>
void otl_write_row(OTLStream& s,Arg1&& arg1,Args&&...args);

Here are the signatures of the nonvariadic template functions for pre-C++11 compilers:

template<typename OTLStream,typename Arg1> void otl_read_row(OTLStream& s,Arg1& arg1);
template<typename OTLStream,typename Arg1,typename Arg2> void otl_read_row(OTLStream& s,Arg1& arg1,Arg2& arg2);
...
template<typename OTLStream,typename Arg1> void otl_write_row(OTLStream& s,Arg1& arg1);
template<typename OTLStream,typename Arg1> void otl_write_row(OTLStream& s,const Arg1& arg1);
template<typename OTLStream,typename Arg1,typename Arg2> void otl_write_row(OTLStream& s,Arg1& arg1,Arg2& arg2);
template<typename OTLStream,typename Arg1,typename Arg2> void otl_write_row(OTLStream& s,const Arg1& arg1,const Arg2& arg2);
...

Here are the signatures of the nonvariadic functions for Visual C++ 2010, and Visual C++ 2012, which do not support variadic templates, but do support universal references (see the explanation below at the end of this page):

template<typename OTLStream,typename Arg1> void otl_read_row(OTLStream& s,Arg1& arg1);
template<typename OTLStream,typename Arg1,typename Arg2> void otl_read_row(OTLStream& s,Arg1& arg1,Arg2& arg2);
...
template<typename OTLStream,typename Arg1> void otl_write_row(OTLStream& s,Arg1&& arg1);
template<typename OTLStream,typename Arg1,typename Arg2> void otl_write_row(OTLStream& s,Arg1&& arg1,Arg2&& arg2);
...

The list of nonvariadic template functions goes up to 15 parameters. The intention here is that similar (even though more limited) functionality should be available to users of pre-C++11 compilers. When such users migrate their C++ code to a C++11 compiler, everything should just work.

The functions are intended for reading / writing whole logical rows, and they automatically check at the end of the argument list whether the "end-of-row" condition is true or not. It completely eliminates the "row tearing" problem. If the condition is false, OTL throws the END-OF-ROW check failed exception. The use of the functions is pretty straightforward:

    otl_write_row(s,f1); is equivalent to s<<f1<<endr;
otl_write_row(s,f1,f2); is equivalent to s<<f1<<f2<<endr;
...
otl_read_row(s,f1); is equivalent to s>>f1>>endr;
otl_read_row(s,f1,f2); is equivalent to s>>f1>>f2>>endr;
...
where s is an otl_stream, and f1, f2... are variables of the data types that are supported by the otl_stream operators >>()/<<(). The functions are defined in the global namespace. In order to retrieve information on NULL values, instantiations of the otl_value<T> template can be used as parameters that get passed into the otl_read_row / otl_write_row functions, for example:

   otl_value<int> f1;
   otl_value<otl_datetime> f2;
   otl_value<std::string> f3;
   ...
   otl_write_row(s,f1,f2,f3);
   ...
   otl_read_row(s,f1,f2);
   ...

There is a subtle difference between the variadic version of these template functions and the nonvariadic version for pre-C++11 compilers. The variadic otl_write_row() uses universal references that accept all types of parameters. The nonvariadic versions of otl_write_row() for pre-C++11 compilers accept either all const T&, or all non-const T&, which is more limited than the variadic version. The nonvariadic versions of otl_write_row() for Visual C++ 2010/2012 accept all types of parameters. "Universal references" is a term coined by Scott Meyers. There is plenty of videos, or articles by Scott Meyers, so if you're curious, just google "universal references C++".


Go Home

Copyright © 1996-2024, Sergei Kuchin, email: skuchin@gmail.com, skuchin@gmail.com .

Permission to use, copy, modify and redistribute this document for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.