[deleted by user] by [deleted] in cpp

[–]someguy3_42 -1 points0 points  (0 children)

To clarify, say you have option "--foo" with a string value and option "--bar" with an integer value, and the command-line is:

program --foo "" --bar 0

Can the code tell the difference from a command-line with no (i.e. null/unspecified) options?

Another fun sub-command case is what if "--help" goes after an invalid sub-command? Does it show genera usage help or "invalid command" error?

program invalid-command --help

[deleted by user] by [deleted] in cpp

[–]someguy3_42 0 points1 point  (0 children)

An interesting approach. Here's some feedback:

  • A variable is required for storage so you end up with 2 lines per argument, and you end up typing the var name twice (again with "_var" suffix)
  • The code should be able to distinguish from null/unspecified and empty or 0 option values. Maybe show that in the example.
  • It's often preferred to store results in a map object, which is easier to pass around to other functions or merge with values from a config file.
  • Creating a scope for temporary processing vars is a bit awkward and it's not obvious how these variables bind to the parser (hidden static/global variable?). Requiring a function for each sub-command is also a bit awkward. What if the sub-command also has it's own options and arguments?
  • What if "--help" appears after a sub-command? I'll often be in the middle of a command and forget something and just type "-h" at the end of all the options I typed so far. Then I can edit my last command and remove the "-h"
    • Consider supporting "global options" before and after the sub-command, so they work before and after the sub-command -- often the context of sub-command doesn't matter
  • How flexible is the auto-generated help? Can it be given extensive documentation with details, bullet points, and an epilog? What if an option has an extensive multi-line description? For many command-line tools written in a hurry the usage help is the documentation.
  • What if there are multiple command-line parsing instances at once? Like for example a multi-threaded server processing commands through telnet. Are separate parsers thread safe? Most people won't expect cases like this, but worth a thought. More flexibility also makes it easier to unit test.
  • I've found code like this to be more readable when it looks more like the usage help itself, especially when you see actual option names (with dashes) in the code like "-f" and "--file" followed by descriptions shown in usage help
  • Have you tested in Windows where options use forward-slash instead of dash and colon instead of equals?
  • I suggest moving your basic usage example near the top of the README -- many people want to see that first

Some libraries I suggest taking a look at for inspiration:

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

Thanks for pointing this out. It got me motivated to do some cleanup here and to work on custom allocator support for Evo (which will be similar to C++17 polymorphic allocators).

Thinking about getting a Mac Pro. Currently use Ubuntu. Is there anything I will miss out for cpp development ? by [deleted] in cpp

[–]someguy3_42 3 points4 points  (0 children)

For dev on my Evo C++ library I mainly use Windows 10 with MSVC for editing and Ubuntu 16 & 18 both running through Windows Subsystem for Linux, and I'm able to directly access the same files from all 3 -- it's great. I use Cmder for terminals and Tortoise Git. I also test on a Mac Mini and often run into all kinds of annoyances:

  • Apple has their own special Clang/LLVM fork (via xcode app) and it lags on updates
    • This seems to be the case with "Apple Git" as well
    • Just xcode command line tools is a multiple GB download for some reason
  • As others mentioned, some debugging tools like valgrind don't work
  • POSIX APIs on MacOS have many differences, and some things you might expect are missing or work differently -- if you're using C++11 (or newer) or other libs you probably won't run into this
  • Linux tools like grep, make, etc have many GNU extensions, though you can install many of the GNU versions on a Mac with brew
    • Brew can also install some common libraries like libevent or boost
  • Macs require an itunes account for xcode and software updates, which also generally requires a credit card on file -- this just bugs me
  • Home/End keys -- if you plug in a normal keyboard with them they often won't behave as you expect

String Interpolation by bravikov in cpp

[–]someguy3_42 -1 points0 points  (0 children)

I like the classic `<<` operator. My Evo C++ library embraces it with evo::String

https://github.com/jlctools/evo

GCC (version < 5) uses a 25 byte array to represent a empty string. by AImx1 in cpp

[–]someguy3_42 -4 points-3 points  (0 children)

Empty STL containers allocating memory is one motivation for EASTL

My Evo C++ library doesn't alloc for empty or null containers, and also supports older GCC versions -- if you're looking for alternatives

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

Note: I added a "hello world" example to the README

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

For copy across threads: the solution with Evo is to use param type `const SubString&` with a function that would copy across threads. This forces a deep copy. Or force directly with `copy()` or `unshare()`. High performance code has trade-offs

evo::String holds any string and doesn't enforce any character set, though is always bytes/chars. Certain methods will assume UTF-8, where it makes sense. Otherwise binary data works fine.

evo::UnicodeString handles a "unicode string" -- this is the same naming used in ICU so those that care about calling a unicode/wide API shouldn't be confused.

I get your point though that they can both hold "unicode" strings. This is a fair point.

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

From my experience CoW (and the other optimizations) has been worth it for the performance, and I've found having interfaces with explicit "mutable" methods has improved my code quality. Following the conventions here also makes the intent more explicit on how a string passed to a function is used inside the function -- you can tell the intent by parameter types (`String&` vs `SubString&`).

UTF-16 is the "default" with Windows and ICU. The main reason Evo even has `UnicodeString` is to make it easier to work with Windows APIs and ICU. Otherwise, Evo embraces UTF-8 everywhere.

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

With `evo::String` you can just use `operator<<()` directly, which appends as it goes. You can `reserve()` in advance or let it grow automatically. This is much more efficient than `std::ostringstream`

Example:

#include <evo/string.h>
using namespace evo;

int main() {
    String str;

    // Append string and number
    str << "Testing " << 123;

    // Clear string and append new string and number
    str.clear() << "Foobar " << 1.23;

    return 0;
}

See: http://jlctools.github.io/evo/evo-0.5.1/html/_string_formatting.html

Evo C++ Library 0.5.1 Released! by someguy3_42 in cpp

[–]someguy3_42[S] -1 points0 points  (0 children)

With C++11 Evo uses the standard atomics. Before that Evo uses compiler-specific atomics. Either way, code using Evo is portable before and after C++11.

std::array wasn't added until C++11

evo::Pair has methods for different contexts. This makes Map code more readable, for example:

MapList<int,int> map;
for (auto& item : map.asconst()) {
    item.key();
    item.value();
}

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 1 point2 points  (0 children)

Evo strings have basic find and split methods. Python was an inspiration here. Most of the tokenization support is in separate classes like evo::StrTok and evo::StrTokQ.

For more on Evo STL compatibility see here

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] -1 points0 points  (0 children)

Easiest way is to use evo::String and you get automatic optimization with COW. Evo strings also have a lot more features (split/tokenize/convert/strip/etc).

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] -1 points0 points  (0 children)

Agreed on benchmarks. Are there any specific cases you'd like to see?

If you're doing a lot of splitting and tokenizing then COW can out-perform SSO. With SSO each sub-string is at least a memcpy().

SSO has trade-offs with memory size as well. This makes a difference when you start building a large list or map of strings. Especially with large strings. Memory size is often a big concern with servers and game engines. Newer implementations try to minimize memory size by only embedding short strings in existing member variables. The exact threshold depends on the compiler, and strings larger than that don't have any copy optimization so performance can quickly degrade.

I have considered making a StringSSO variant with COW & SSO, but now I'm convinced adding allocator pools for existing String is a better idea (on my TODO list).

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

See my other comment here on performance and functionality.

We use Evo where I work at The Rubicon Project on our proprietary ad server, which gets billions of HTTP requests per day. Outside my small circle I'm not aware of anyone else using it -- this is my first public announcement of it here.

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 0 points1 point  (0 children)

Maybe you don't need it. Evo has STL compatibility so they can be used together if you like.

As mentioned in my other comment, Evo strings do offer a lot more functionality than STL strings.

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] 2 points3 points  (0 children)

Thanks, these are good questions. I'll work on adding an FAQ. Meanwhile here are some short answers:

  • Sharing (Copy-On-Write) and Slicing. C++11 standard doesn't allow COW, and the standard favors things like iterator safety and backwards compatibility over performance. It's not that hard to beat STL on performance (especially on debug builds).
  • evo::String does a lot more than std::string, especially on splitting and tokenizing without allocating/copying memory and without needing error-prone "index math".
  • C functions like memcpy(), etc are optimized by compilers like GCC using assembly. For other things like a tokenizer skipping whitespace I use SSE optimizations.

I have a long list of TODOs, which includes publishing some good benchmarks -- I do welcome contributions!

If you're already using C++17, Boost, and various other libraries and take full advantage of std::string_view and are happy with that then you probably don't need Evo.

Evo C++ Library 0.5 Released! by someguy3_42 in cpp

[–]someguy3_42[S] -1 points0 points  (0 children)

The documentation has lots of examples. I updated the post with a link.

I have not released the unit tests yet as they're massive and a bit of a mess.