About myself
I myself am a C ++ programmer, or rather, I am just a beginner, with no commercial experience. Initially, I got acquainted with the C language, and discovered C ++ as a powerful extension of the C language. In my opinion, it adds those necessary useful things that are not in C (function overloading, classes, namespaces, etc.), while these things perfectly expand the philosophy language
The idea
C 2011 "" . (Generic selection) , - ,
: () print
, . , , . C11
, . , :
. . , , :
,
" ",
:
__VA_ARGS__
__VA_OPT__
VA_ARGS
VA_OPT.
__LINE__ __FILE__
:
\
, . 20 5 ,
&
&
,<
<
-
-
, ( 700) . . -
, , . , . ! :) png
print(x)
int, float
char*
(cstring):
void print_int(int x) {printf("%d ", x); }
void print_float(float x) {printf("%.4f ", x); }
void print_string(char* x) {printf("%s ", x); }
print
:
#define print(x) _Generic((X),\
int: print_int,\
float: print_float,\
char*: print_string)\
(x)
, print("hi")
print_string("hi")
, print(5.5)
print_float(5.5)
print("hi")
_Generic(("hi"), int: print_int, float: print_float, char*: print_string)("hi"),
, _Generic(...)
. print_int
void print_int(int n, ...)
{
va_list argptr;
va_start(argptr, n);
int x;
for (int i = 0; i < n; i++)
{
x = va_arg(argptr, int);
printf("%d ", x);
}
va_end(argptr);
}
, :) n
,
PP_NARG(...),
#ifndef PP_NARG
/*
*
* The PP_NARG macro returns the number of arguments that have been
* passed to it.
*
* https://groups.google.com/g/comp.std.c/c/d-6Mj5Lko_s
*
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_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, N, ...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif
#define print(...) print_int(PP_NARG(__VA_ARGS__), __VA_ARGS__)
: __VA_ARGS__
, ...
, ,
#define function(x, ...) Generic((x),\
int: function_int,\
float: function_float,\
char*: function_string)\
(PP_NARG(__VA_ARGS__) + 1, x, __VA_ARGS__)
function
, . function
, print
, . , , ,
I.
( ) hidden_print(sep, n, x1, x2, x3, ...),
xi
printf.
12. print
' .
cool
. - , , , , . c++ cool
, , . #define print cool_print
, #undef print
cool_hidden_types[12]
, cool_hidden_last
, cool_hidden_add_int
, cool_hidden_add_float
.. , . 7 : int, char*, float, double, char (?), uint, long
char (?)
- _Generic(('a'), char: fun_char)()
- " int
", int
#define
, enum
. , !
#define COOL_HIDDEN_INT 0
#define COOL_HIDDEN_STRING 1
#define COOL_HIDDEN_FLOAT 2
#define COOL_HIDDEN_DOUBLE 3
#define COOL_HIDDEN_CHAR 4
#define COOL_HIDDEN_UINT 5
#define COOL_HIDDEN_LONG 6
#define COOL_HIDDEN_VOID 7
int cool_hidden_types[12];
int cool_hidden_last = 0;
void cool_hidden_add_int()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_INT;
cool_hidden_last += 1;
}
void cool_hidden_add_string()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_STRING;
cool_hidden_last += 1;
}
/* */
void cool_hidden_add_void()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_VOID;
cool_hidden_last += 1;
}
COOL_HIDDEN_VOID
, . 16- ,
generic cool_hidden_add(x)
, x
#define cool_hidden_add(x) \
_Generic((x), \
int: cool_hidden_add_int, \
char*: cool_hidden_add_string, \
float: cool_hidden_add_float, \
double: cool_hidden_add_double, \
char: cool_hidden_add_char, \
unsigned int: cool_hidden_add_uint, \
long: cool_hidden_add_long, \
default: cool_hidden_add_void \
)()
...
II.
, cool_print##n(x1, x2, ..., xn)
("##" n
), xi
, cool_hidden_print(sep, n, x1, x2, ...)
, n
, xi
. ( ) cool_print_sep = " "
,
. , . ( visual studio , , )
:
#define cool_print_n(x1, x2, x3, x4, ..., xn, ...)\
cool_hidden_add(x1);\
cool_hidden_add(x2);\
cool_hidden_add(x3);\
cool_hidden_add(x4);\
................... \
cool_hidden_add(xn);\
cool_hidden_print(cool_print_sep, n, x1, x2, x3, x4, ..., xn)
//hide this a big part of code
#if 1
#define cool_print_12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_add(x11); \
cool_hidden_add(x12); \
cool_hidden_print(cool_print_sep, 12, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)
#define cool_print_11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_add(x11); \
cool_hidden_print(cool_print_sep, 11, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
#define cool_print_10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_print(cool_print_sep, 10, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)
#define cool_print_9(x1, x2, x3, x4, x5, x6, x7, x8, x9, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_print(cool_print_sep, 9, x1, x2, x3, x4, x5, x6, x7, x8, x9)
#define cool_print_8(x1, x2, x3, x4, x5, x6, x7, x8, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_print(cool_print_sep, 8, x1, x2, x3, x4, x5, x6, x7, x8)
#define cool_print_7(x1, x2, x3, x4, x5, x6, x7, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_print(cool_print_sep, 7, x1, x2, x3, x4, x5, x6, x7)
#define cool_print_6(x1, x2, x3, x4, x5, x6, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_print(cool_print_sep, 6, x1, x2, x3, x4, x5, x6)
#define cool_print_5(x1, x2, x3, x4, x5, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_print(cool_print_sep, 5, x1, x2, x3, x4, x5)
#define cool_print_4(x1, x2, x3, x4, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_print(cool_print_sep, 4, x1, x2, x3, x4)
#define cool_print_3(x1, x2, x3, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_print(cool_print_sep, 3, x1, x2, x3)
#define cool_print_2(x1, x2, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_print(cool_print_sep, 2, x1, x2)
#define cool_print_1(x, ...) \
cool_hidden_add(x); \
cool_hidden_print(cool_print_sep, 1, x)
#endif //hide this a big part of code
, cool_print_n
12, ...
,
PP_NARG(__VA_ARGS__
) cool_print_##PP_NARG(__VA_ARGS__)
, - cool_print_PP_NARG("x", 5, "i", 8,),
. , ,
PP_NARG(__VA_ARGS__)
#ifndef PP_NARG
/*
*
* The PP_NARG macro returns the number of arguments that have been
* passed to it.
*
* https://groups.google.com/g/comp.std.c/c/d-6Mj5Lko_s
*
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_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, N, ...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif
cool_print(...) - PP_NARG,
#define cool_print(...) \
cool_print_(__VA_ARGS__ , COOL_RSEQ_N())
#define cool_print_(...) \
COOL_ARG_N(__VA_ARGS__)
#define COOL_ARG_N( \
_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, n, ...) \
\
cool_print_##n(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11,_12)
#define COOL_RSEQ_N() \
63,62,61,60,59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
:
1. cool_print("a", 4, "b")
2. cool_print_("a", 4, "b",
63,62,61,60,59,58,57,56,55,54,
53,52,51,50,49,48,47,46,45,44,43,
42,41,40,39,38,37,36,35,34,33,32,
31,30,29,28,27,26,25,24,23,22,21,
20,19,18,17,16,15,14,13,12,11,10,
9,8,7,6,5,4,3,2,1,0
3. cool_print_ COOL_ARG_N,
64 . 64- , n
- ,
VA_ARGS COOL_RSEQ_N
(63..0)
4. COOL_ARG_N
cool_print_##n .
cool_print_3
cool_print_3("a", 4, "b",
63,62,61,60,59,58,57,56,55,54,53,52,51,50,
49,48,47,46,45,44,43,42,41,40,39,38,37,36,
35,34,33,32,31,30,29,28,27,26,25,24,23,22,
21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3)
12 , .
, "..."
cool_print_##n
64 12,
III.
, cool_print("", "", 10)
cool_hidden_types
, cool_hidden_print(int sep, int n, ...)
!
C
<stdarg.h>
, . :
...
va_list argptr
-argptr
,
va_start(argptr, n)
-
va_arg(argptr, float)
-
va_end(argptr)
-
- ,
: . swich'e void' x, printf("...%s", *((type) x), sep)
, type
- , "..." - . int
printf("%d%s", *((type) x), sep)
. #define COOL_CAST(T, x) ((T) (x))
cool_hidden_print(sep, n, ...)
#define COOL_CAST(T, x) ((T) (x))
void cool_hidden_print(char* sep, int n, ...)
{
va_list argptr;
va_start(argptr, n);
void* x;
for (int i = 0; i < n; i++)
{
switch (cool_hidden_types[i])
{
case COOL_HIDDEN_INT:
x = &va_arg(argptr, int);
printf("%d%s", COOL_CAST(int, x), sep);
break;
case COOL_HIDDEN_STRING:
x = &va_arg(argptr, char*);
printf("%s%s", COOL_CAST(char*, x) , sep);
break;
case COOL_HIDDEN_FLOAT:
x = &va_arg(argptr, float);
printf("%.4f%s", COOL_CAST(float, x), sep);
break;
case COOL_HIDDEN_DOUBLE:
x = &va_arg(argptr, double);
printf("%.4f%s", COOL_CAST(double, x), sep);
break;
case COOL_HIDDEN_CHAR:
x = &va_arg(argptr, char);
printf("%c%s", COOL_CAST(char, x), sep);
break;
case COOL_HIDDEN_UINT:
x = &va_arg(argptr, unsigned int);
printf("%.4u%s", COOL_CAST(unsigned int, x), sep);
break;
case COOL_HIDDEN_VOID:
printf("unsupported type%s", sep);
break;
default:
printf("Internal COOL/C/PRINT error line: %d in %s", __LINE__, __FILE__);
break;
}
}
va_end(argptr);
cool_hidden_last = 0;
}
, , . va_arg
printf
cool_
#define print cool_print
, print
! println
,
#define cool_println(...) \
cool_print(__VA_ARGS__); printf("\n")
#define cool_printlnn() printf("\n")
, - , printlnn()
... , cool_print
#define cool_print(...) cool_print_(__VA_ARGS__ , ## COOL_RSEQ_N()
#define cool_print(...) cool_print_(__VA_ARGS__ ## , COOL_RSEQ_N()
. ,## __VA_ARGS__
, __VA_ARGS__
,
- , __VA_ARGS__
. 2
__VAR_OPT__
, , , , ,
- (,)
, visual stidio __VAR_OPT__
. __VAR_OPT__
, 63 64 ( cool_print##n
( ). -
#define cool_print(...)\
__VAR_OPT__( cool_print_(__VA_ARGS__ , COOL_RSEQ_N()) )
#define cool_print(...) \
cool_print_(__VA_ARGS__ , COOL_RSEQ_N())
- ,
#define cool_print(...)\
cool_print_("", __VA_ARGS__)
#define cool_print_(...) \
cool_print__(__VA_ARGS__ , COOL_RSEQ_N())
#define cool_print__(...) \
COOL_ARG_N(__VA_ARGS__)
,
- . , ,
- . C++ . ,
print
- . visual studio
print
println
" ", ( ) . . , variadic templates c++, ( - )
. ,
: print.h
. . , - . C++, , id ; , ( pow, powi, powf
); , , , , . -
print
C++:
print C++
#ifndef COOL_PRINT_HPP
#define COOL_PRINT_HPP
#include <string>
#include <iostream>
#include <iomanip>
namespace
{
std::ostream* out = &std::cout;
}
namespace cool
{
inline void setCyrillic()
{
setlocale(LC_ALL, "Russian");
}
void setPrintOut(std::ostream& os)
{
::out = &os;
}
std::ostream* getPrintOutPtr()
{
return ::out;
}
inline void printFlush()
{
*::out << std::flush;
}
inline void print()
{
*::out << ' ';
}
template <typename Arg>
inline void print(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg << ' ';
}
template <typename Arg, typename... Args>
void print(const Arg& arg, const Args&... args)
{
print(arg);
print(args...);
}
////
inline void println()
{
*::out << '\n';
}
template <typename Arg>
inline void println(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg << '\n';
}
template <typename... Args>
void println(const Args&... args)
{
print(args...);
println();
}
///
void print0() { }
template <typename Arg>
inline void print0(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg;
}
template <typename Arg, typename... Args>
void print0(const Arg& arg, const Args&... args)
{
print0(arg);
print0(args...);
}
#define COOL_INFO(x) (std::string(#x) + " = " + std::to_string(x))
}
#endif
More understandable, about 3 times less code, and the implementation is more complete. But at the same time, the standard one, printf
although it does not look so elegant, is fast and practical. Each language has its place