Recent Entries 10
- pattern minor 112d agoRotate a given number of variables in-placeA very simple but useful algorithm: rotate the values of a given number of variables in-place to the left so that the first variable gets the value of the second, the second gets the value of the third, etc... and the last variable gets the value of the first one. ``` #include #include template struct are_same: std::conjunction...> {}; template auto rotate_left_inner(T& first, T& second, Args&... args) -> T& { first = std::move(second); if constexpr (sizeof...(Args) == 0) { return second; } else { return rotate_left_inner(second, args...); } } template auto rotate_left(Head& first, Tail&... args) -> void { static_assert(are_same::value, "elements passed to rotate_left shall have the same type"); if constexpr (sizeof...(Tail) > 0) { auto tmp = std::move(first); auto& last = rotate_left_inner(first, args...); last = std::move(tmp); } } ``` This function can be used as follows: ``` int a=0, b=1, c=2, d=3, d=4; rotate_left(a, c, e); rotate_left(b, d); // Now (a, b, c, d, e) = (2, 3, 4, 1, 0) ``` The code above generated the same assembly than the hand-rolled version when I gave it five integers to rotate in the compiler explorer, with both GCC and Clang. I wanted to make a companion `rotate_right` function, but repeatedly finding the last element of a template parameter pack is not as easy, so the easiest solution for a programmer is to pass the variables to rotate to `rotate_left` in reverse order. Do you see any way to improve this simple algorithm? Anything that I might be missing?
- pattern minor 112d agoImplementing printf to a string by calling vsnprintf twiceI'm experimenting with writing a dynamic string library in C, and I decided to write an implementation of sprintf. In my code, I call `vsnprintf` with a buffer of 0 bytes, just so I can get the number of bytes it requires. I was wondering if there is anything wrong with this code and if there a better way to do this. It feels wrong to me, but I can't seem to think of a better way to do so yet have the same effect. ``` string string_printf(const char *fmt, ...) { va_list in, copy; string a = NULL; int size; /* start the main input */ va_start(in, fmt); /* make a copy of the input */ va_copy(copy, in); /* run vsnprintf just to see how much bytes needed */ size = vsnprintf(a, 0, fmt, copy) + 1; va_end(copy); /* allocate the amount now */ a = string_new_size(size); string_to_sr(a)->len = size - 1; /* re-run */ vsnprintf(a, size, fmt, in); va_end(in); /* done */ return a; } ```
- pattern minor 112d agoSleeping and invoking a task in Python 2.X and Python 3.XI'm writing a program that needs to be compatible for both Python 2.X and Python 3.X. My problem is that, because of the differences between these two versions, I'm duplicating code. ``` try: ### Python 2.X part time.sleep(iterator.next()) if len(arguments) >= len(inspect.getargspec(task).args): task(*arguments) else: print("ERROR: There is a mismatch between the number of" " arguments provided in `arguments` and the ones" " needed by the task function.") except AttributeError: ### Python 3.X part time.sleep(next(iterator)) if len(arguments) >= len(inspect.getfullargspec(task).args): task(*arguments) else: print("ERROR: There is a mismatch between the number of" " arguments provided in `arguments` and the ones" " needed by the task function.") ``` It can be seen that both versions only differ in the usage of `next()`, `inspect.getargspec()` and `inspect.getfullargspec()`, while the other logic remains the same. Is there any way to optimize the execution of the tasks, in `tasks(*arguments)`, and the printing of the error messages, so that I don't have to repeat the same code? This is just sample working code, but I mean my question in a more broader and general case.
- pattern moderate 112d agoVariadic templated method to extract values from a tableIs this the correct, most sane way to do variadic templates in C++? All that this function does is to see if gate has a key, if it has, it adds it to a vector of values, if not, it default constructs an object in place. This function belongs to a templated class called `core_table` where `K` is the key type and `V` the value type. ``` template std::vector values_at(Args const & ...args) const { std::initializer_list input {args...}; std::vector output; output.reserve(input.size()); for (auto const & e : input) { auto const it = gate.find(e); if (it != gate.end()) { output.emplace_back((*it)->second); continue; } output.emplace_back(); } return output; } ``` I'm asking it because all the examples of variadic templates that I saw until now made use of recursion. I'm still in a state of desbelief that I can just write `std::initializer_list input {k, args...};` and iterate over it, I literally didn't knew until now that this was possible - this does make variadic templates much more approachable in C++, at least for me. So, is this a good example? How can I make it better, more optimized? Working Example ``` #include #include #include #include #include using std::cout; using std::endl; template class core_table { using value = std::pair; using chain = std::list; using iterator = typename chain::iterator; using const_iterator = typename chain::const_iterator; struct compare { using is_transparent = void; bool operator ()(const_iterator x, const_iterator y) const { return x->first first; } bool operator ()(const_iterator x, K const & k) const { return x->first first; } }; chain data; std::set gate; public: core_table() = default; core_table(core_table && ct) = default; core_table(core_table const & ct) { for (auto const & e : ct) { push(e.firs
- pattern minor 112d agoTypesafe scanf-like function with variadic templatesI'm hoping to get some feedback on a function with variadic templates that parses a format string and fills in some parameters whose order and types are based on the characters in the format string. Kind of like `scanf()`. (For the curious, I am trying to make a typesafe version of this function, documentation here.) I'm pretty experienced with C but the last time I did anything serious with C++ was at university 15 years ago and it seems like a completely different language now. This toy code works for me and fails in the ways I'd expect it to when I give it bad input. However, I'm not too familiar with the standard library so I have a strong feeling that I may be missing something. Also the code seems overly verbose for what it does. So here's what I'm hoping to find out: - Is this code idiomatic modern C++? - Am I overlooking useful features in the standard library that would make things easier? - Should I be using pointers in this way, or am I thinking too much in C? - Should I consider another approach entirely, like `tscanf(format, paramname1, paramname2) >> param1 >> param2`? I am constrained to use C++11, the code currently does not use Boost. ``` #include #include struct SomeStruct { int val; }; template bool assign(const char c, T& ref) { return false; } template<> bool assign(const char c, bool*& ref) { if (c != 'b') return false; *ref = true; return true; } template<> bool assign(const char c, int*& ref) { if (c != 'i') return false; *ref = 42; return true; } template<> bool assign(const char c, SomeStruct& ref) { if (c != 'h') return false; ref.val = 81; return true; } template bool tscanf(const char *format, const char *name, T& ref) { if (std::strlen(format) != 1) { std::cerr bool tscanf(const char *format, const char *name, T& ref, Args... args) { if (!assign(format[0], ref)) { std::cerr << "Wrong type for argument " << name << std::endl;
- pattern minor 112d agoA variadic C function for concatenating multiple stringsI have this function that takes a number \$N\$, and \$N\$ C strings, concatenates and returns the result: ``` #include #include #include #include char* mystrcat(int count, ...) { char** p; char* result; char* ptr; size_t* len_array; va_list ap; int j; size_t total_length; if (count < 1) { return ""; } va_start(ap, count); p = malloc(sizeof(char*) * count); len_array = calloc(count, sizeof(size_t)); total_length = 0; for (j = 0; j != count; ++j) { p[j] = va_arg(ap, char*); total_length += (len_array[j] = strlen(p[j])); } result = malloc(sizeof(char) * (total_length + 1)); ptr = result; for (j = 0; j != count; ++j) { strcpy(ptr, p[j]); ptr += len_array[j]; } *ptr = '\0'; va_end(ap); return result; } int main(int argc, char* argv[]) { puts(mystrcat(5, "Hello", ", ", "world", ", ", "friends!")); } ``` As always, please tell me anything that comes to mind.
- pattern minor 112d agoSimple JavaScript precondition checking implementationI am writing a JavaScript application and would like to validate function arguments in many places. Most of these checks will be for correct argument types, or numeric values within specific ranges. Here is a simple function I came up with to check any number of preconditions: ``` function requires(conditions) { for (var cond in arguments) { if (typeof cond !== "boolean") throw "Preconditions must be boolean expressions {" + cond + "}"; if (cond !== true) throw "Precondition failed {" + cond + "}"; } } ``` It would be used like this: ``` function alertChar(message, index) { requires( typeof message === "string", typeof index === "number", index >= 0, index < message.length); alert(message.charAt(index)); } ``` Is there anything conceptually wrong with this simple implementation? Is there a way I can make it lazily evaluate each precondition expression? Is accessing the `arguments` array inefficient?
- pattern minor 112d agoConcatenate two containers, e.g. vector or stringsI'd like to create a function that can concatenate vectors or strings. It must - Keep correct order - Be optimal This is the solution I came up with: ``` template V concatenate( V&& v ) { return v; } template V1 concatenate( V1 v1, V2&& v2, Rest&&... rest) { v1.insert( v1.end(), v2.begin(), v2.end() ); return concatenate( std::move(v1), std::forward(rest)... ); } // usage: std::vector v1 = { 1, 2, 3 }; std::vector v2 = { 4, 5, 6 }; std::vector v3 = { 7, 8, 9 }; std::vector v12 = concatenate( v1, v2 ); std::vector v123 = concatenate( v1, v2, v3 ); std::vector vm12 = concatenate( std::move(v1), v2 ); std::vector vm23 = concatenate( v2, std::move(v3) ); ``` Is my argument forwarding correct here? Is this the simplest solution?
- pattern minor 112d agoCall a lua function - the C++ wayI'm not that good when it comes to templates, especially when it comes to variadic templates. I want to show you some code where I use both - templates and variadic templates - to call a lua function. I'm proud that it works, and it works great, but I want to get some feedback on what I could've done better. ``` template bool run_script(int id, Args && ... args) { const int params = sizeof...(args); _load(id); push(std::forward(args)...); return _run(params); } ``` This is the "entry point". `_load` will just load the lua-function onto the stack and `_run` will run it with `params` arguments. The important part is the `push` function. ``` template void push(T && arg) { _push(std::forward(arg)); } template void push(T && arg, Args && ... other) { _push(std::forward(arg)); push(std::forward(other)...); } void _push(int arg) { lua_pushinteger(L, arg); } void _push(const std::string& arg) { lua_pushstring(L, arg.c_str()); } void _push(const char* arg) { lua_pushstring(L, arg); } ``` I had a problem before, where I had all of them named `push`, but for some reason it couldn't push a `std::string` (std::string as argument choose the template instead of `const std::string&`) but now with the templates called `push` and the functions which do the work `_push` it's working great. It's not much code, I know, but it's my the first time working with variadic templates and it took me a fair amount of time to get it working.
- pattern minor 112d agoImplementing checksum add without carry in CI need to write a function in C which performs a checksum using the rule "add without carry". As I understand it, the "add without carry" concept is equivalent to the bitxor operator and given that the bitxor operation is associative and commutative, I am relying on that to perform the calculation. Below is my function. Note that the input is in decimal format and the checksum is of the binary digits with final output being in decimal format. ``` UCHAR checksumAddWoCarry(int num, ...) { va_list valist; /* List of variable arguments */ UINT arg1, arg2; /* The first two arguments from the va_list */ int i; /* Iterator */ UINT result; /* Storage for returned result */ va_start(valist, num); /* Start the usage of the list */ arg1 = va_arg(valist,UINT); /* Pull out the first two variable arguments */ arg2 = va_arg(valist,UINT); result = arg1 ^ arg2; if (num > 2) { for (i = 2; i < num; i++) { result ^= va_arg(valist,UINT); } } va_end(valist); return (UCHAR)result; } ``` An example call would be ``` result = checksumAddWoCarry(3, 4,5,6); ``` where I expect that `result` is `7`. I would like an answer to two related questions. - Is my logic for the implementation correct? Specifically in regards to my use of the bitxor operator to perform the checksum? - I want to know, aside from the logic of the implementation, if my method is a good one. Are there any gotchas I could run into? Is there a better/faster way?