c++ - will It evaluate at compile time? (pass const char* as template parametr) -
working example:
#include <iostream> #include <boost/preprocessor/config/limits.hpp> #include <boost/preprocessor/repetition/repeat.hpp> /////////////////////////////////////////////////////////////////////////////////////////////// // compile-time c-string processing: /////////////////////////////////////////////////////////////////////////////////////////////// #define _debug_mode_ 1 #define _error_chk_ 1 #define my_nullptr nullptr #ifdef _msc_ver #define __func__ __function__ #else #define __func__ __func__ #endif /////////////////////////////////// // configuration: #define buffer_size 100 // limit: 256 // const char buffer[buffer_size]... // not find symbol name "buffer" abstraction #define empty_char '\0' #define default_msg "3w3a]3aw" /////////////////////////////////// // slice char[] separate char's constexpr __forceinline char getcharat (const char* cstr, unsigned int i, unsigned int l) { return (i < l) ? cstr[i] : empty_char; } #define get_char_at(z,n,text) , getcharat(text, n, (sizeof(text) / sizeof(text[0]))) #define slice(_cstr) sizeof(_cstr)/sizeof(_cstr[0]) boost_pp_repeat(buffer_size, get_char_at, _cstr) /////////////////////////////////// // fragments of code repeated: #define arg(z,n,text) , const char text ## n // repeat fragment of code n times // make list of template arguments: #define list(z,n,text) text ## n, // repeat fragment of code n times: // make "body" of initializer list /////////////////////////////////// // repeat _macro "buffer_size" times: #define repeat_macro(_macro, _text) boost_pp_repeat(buffer_size, _macro, _text) /////////////////////////////////// // cast std::string: #define cast_to_string(_cstr) ((std::string)_cstr) /////////// /////////////////////////////////////////////////////////////////////////////////////////////// // errchk: /////////////////////////////////////////////////////////////////////////////////////////////// #define name_of_errchk_variable_file file #define name_of_errchk_variable_from #define name_of_errchk_variable_func func #define name_of_errchk_variable_msg msg template < unsigned int line, // unsigned int length_file, const char file0, const char file1, const char file2, ... , const char filen // n = buffer_size - 1 unsigned int length_file repeat_macro(arg, name_of_errchk_variable_file), // unsigned int length_from, const char from0, const char from1, const char from2, ... , const char fromn // n = buffer_size - 1 unsigned int length_from repeat_macro(arg, name_of_errchk_variable_from), // unsigned int length_func, const char func0, const char func1, const char func2, ... , const char funcn // n = buffer_size - 1 unsigned int length_func repeat_macro(arg, name_of_errchk_variable_func), // unsigned int length_msg, const char msg0, const char msg1, const char msg2, ... , const char msgn // n = buffer_size - 1 unsigned int length_msg repeat_macro(arg, name_of_errchk_variable_msg ) > __forceinline void errchk(bool failure, bool* flag_success = my_nullptr) { if (failure) { // constexpr const char file[] = { file0, file1, file2, ... , filen, '\0' }; // n = buffer_size - 1 constexpr const char file[] = { repeat_macro(list, name_of_errchk_variable_file) empty_char }; // constexpr const char from[] = { from0, from1, from2, ... , fromn, '\0' }; // n = buffer_size - 1 constexpr const char from[] = { repeat_macro(list, name_of_errchk_variable_from) empty_char }; // constexpr const char func[] = { func0, func1, func2, ... , funcn, '\0' }; // n = buffer_size - 1 constexpr const char func[] = { repeat_macro(list, name_of_errchk_variable_func) empty_char }; // constexpr const char msg[] = { msg0, msg1, msg2, ... , msgn, '\0' }; // n = buffer_size - 1 constexpr const char msg[] = { repeat_macro(list, name_of_errchk_variable_msg ) empty_char }; // print error: std::cout << "file: " << name_of_errchk_variable_file << std::endl; std::cout << "line: " << line << std::endl; std::cout << "from: " << name_of_errchk_variable_from << "()" << std::endl; std::cout << "func: " << name_of_errchk_variable_func << std::endl; // print message: if(cast_to_string(msg) != cast_to_string(default_msg)) std::cout << "msg: " << msg << std::endl; // set flag: if (flag_success) *flag_success = false; } #if (_debug_mode_) else { } #endif } /////////// /////////////////////////////////////////////////////////////////////////////////////////////// // macros: /////////////////////////////////////////////////////////////////////////////////////////////// #if (_error_chk_) //> - f stands flag. errchk using bool flag //> - c stands class. errchk using member variables; //> - m stands message errchk print user message. mesage must in format: "my mesage" c-string , nothing else!!! otherwise see grand mother of errors!!! # define errchk(_failure) \ errchk <__line__, slice(__file__), slice(__func__), slice(#_failure), slice(default_msg)> (_failure); # define errchk_f(_failure, _flag) \ errchk <__line__, slice(__file__), slice(__func__), slice(#_failure), slice(default_msg)> (_failure, &_flag); # define errchk_c(_failure, _msg) \ errchk <__line__, slice(__file__), slice(__func__), slice(#_failure), slice(default_msg)> (_failure, &(my_(success))); # define errchk_m(_failure, _msg) \ errchk <__line__, slice(__file__), slice(__func__), slice(#_failure), slice(_msg)> (_failure); #else # define errchk(_failure) \ _failure; # define errchk_f(_failure) \ _failure; # define errchk_c(_failure) \ _failure; # define errchk_m(_failure) \ _failure; #endif /////////// /////////////////////////////////////////////////////////////////////////////////////////////// // main:: /////////////////////////////////////////////////////////////////////////////////////////////// int main(int argc, char ** argv) { bool failure = true; errchk(failure); getchar(); } ///////////
edit:
basically want work templates. hoping pass char's (file0
file1
file2
... , func0
func1
func2
...) @ compile-time function body. concatenate them c-string cstr_file
or cstr_func
(again @ compile-time). , @ run-time print constants when failure == true
.
template accepts 2 * buffer_size + 1
arguments on 500 of them @ current configuration
is example doing that?
hoping "specializing template variable" right tool do. c-string passed template split("...")
macro, known @ compile time.
edit #2:
@olpa told me example bug'y. have re-upload newest 100% working version.
Comments
Post a Comment