ark::core

Enums

  • CodeGenerationFlags
    Options that can be provided to the code generation.

  • WriteOptions (uint32_t)
    Represents available options when writing strings out to files. This is a bitmask, you can specify multiple options.

  • PollEventFlags
    Flags to indicate if you want to listen for this descriptor to be ready for reading or writing.

  • ThreadScheduler
    An enumeration of potential thread schedulers. Right now, this maps directly to Linux/pthread schedulers.

Typedefs

Defined in “ark/core/argument_parser.hh”:

Defined in “ark/core/event_condition.hh”:

Defined in “ark/core/forward.hh”:

  • using PollablePtr = std::shared_ptr< Pollable >

Classes

  • ark::core::ArgumentParseResult
    This object is returned after parsing a series of arguments, and contains the results of the parse. Use this to determine which arguments were selected.

  • ark::core::ArgumentParser
    An argument parser is a class that can consume command line arguments (typically from an int main()) routine, and parse them into a list of configuration options.

    This generally follows the GNU-style rules, with short and long options, and a double dash to terminate argument parsing.

  • ark::core::ArgumentParserOptionGroup
    Stores an “option group” this is a group of options, mostly intended to give the end user more context.

  • ark::core::ByteBuffer
    A byte buffer is a buffer that is oriented around efficient storage of byte arrays. It has provisions for wrapping arrays, intelligent allocations, growing on demand, and zero-copy support.

    If you copy this structure, you will get a shallow copy by default. Modifying the buffers (via write, or accessing data in a non-const fashion), incurs a copy penalty.

  • ark::core::ByteBufferStreamBuf
    This class forms a streambuf that writes directly to a byte buffer, which can potentially save a few memory copies when using APIs that prefer istream/ostream.

    This is not a complete implementation of a streambuf, but wraps typical use cases.

  • ark::core::CircularBuffer
    Forward declare for the iterator.

    A simple implementation of an STL-like circular buffer. If you prefer a FIFO-style queue, and know the upper limits of how many items will be in that queue, this can save some expansions/memory allocations.

  • ark::core::CircularBufferIterator
    An iterator, used for iterating through items in a circular buffer (or for things like sorting).

  • ark::core::EventCondition
    Provides a simple condition mechanism that allows you to sleep on (and wake up from) listening to a file descriptor. This can be faster that using a mutex and condition variable pair, and can also be nice if you are waiting on other descriptors (such as sockets) and want to also wait on an event.

  • ark::core::Fnv1aHasher
    This is a hasher that can take in arbitrary data and produce a FNV1A hash (64-bit). You can write to it multiple times before you finalize the hash value.

  • ark::core::Guid
    A class that represents a GUID. This GUID is stored as a 16-byte array and is automatically parsed (or converted) into a human readable string form on demand.

  • ark::core::OptionRule
    Represents an option rule. These are the rules that the command line options are parsed from, and are normally instantiated and managed by the ArgumentParser itself.

  • ark::core::ParserRule
    Represents a parser rule these can be either option or positional rules. They provide a minimal interface to both.

  • ark::core::PollSet
    A pollable set represents a set of pollables that can be grouped together and polled to determine if they are ready for reading or writing.

  • ark::core::Pollable
    A virtual class that allows you to return a common native handle that is useful for polling.

  • ark::core::PositionalRule
    Represents a positional rule. These don’t have flags, can appear only once, but can take one or more arguments. They are parsed in order.

    These are the rules that the command line options are parsed from, and are normally instantiated and managed by the ArgumentParser itself.

  • ark::core::ScopeExit
    A simple class that allows you to invoke code once the scope is exiting. This is useful as a ‘finally’ type concept, where you want to ensure some code is run, even if an exception occurs.

  • ark::core::ScopedDirectory
    Scoped class that creates a new directory and will automatically remove it on destruction.

  • ark::core::ScopedUnlock
    Takes in a unique lock, unlocks it, and ensures it is is locked again when this object falls out of scope.

  • ark::core::Url
    A URL represents a string that conforms to the whatwg’s URL representation. It can store a scheme, username, password, hostname, path, and fragment.

  • ark::core::CaseInsensitiveComparator
    Defines a custom comparator, which can be used to make std::map (and other related classes) case-insensitive. This is only valid for simple ASCII strings.

  • ark::core::ParseResult
    A parsed result represents a parsed argument, which contains a reference to the original rule, along with any additional arguments that were provided.

  • ark::core::PollDescriptor
    A structure pair representing a native handle to wait on, and the flags that indicate what we are waiting for.

  • ark::core::ResolvedBacktraceSymbol
    Resolved symbol information the API makes a best effort to populate this information, it might not be precise.

Functions

Declared in “ark/core/algorithm.hh”:

  • size_t count_over_all(const Container & container, const Type & value)
    A wrapper around std::count, which automatically iterates over the entire item in the container given.

     const std::vector<uint64_t> values = {10, 20, 30, 10, 40};
    
     EXPECT_EQ(count_over_all(values, 10), 2);
     EXPECT_EQ(count_over_all(values, 20), 1);
     EXPECT_EQ(count_over_all(values, 50), 0);
    
  • void deduplicate(std::vector< Type > & target)
    Deduplicates all of the items in the given vector.

Declared in “ark/core/ansi.hh”:

  • bool terminal_accepts_ansi()
    Returns true if ANSI is enabled or not on the terminal. For example, if the terminal is a TTY, or ANSI is forced via configuration variable.

Declared in “ark/core/atomic.hh”:

  • void atomic_fetch_max(std::atomic< Type > & current_max, const Type & potential_max)
    Completes an atomic maximum operation, replacing the current max with the potential max atomically.

     std::atomic<uint64_t> max = 0;
    
     atomic_fetch_max<uint64_t>(max, 10);
     EXPECT_EQ(max.load(), 10);
    
     atomic_fetch_max<uint64_t>(max, 15);
     EXPECT_EQ(max.load(), 15);
    
     atomic_fetch_max<uint64_t>(max, 5);
     EXPECT_EQ(max.load(), 15);
    
     atomic_fetch_max<uint64_t>(max, 14);
     EXPECT_EQ(max.load(), 15);
    
     atomic_fetch_max<uint64_t>(max, 20);
     EXPECT_EQ(max.load(), 20);
    

Declared in “ark/core/backtrace.hh”:

  • void install_failure_signal_handlers()
    Installs a number of hooks that print out stack traces when your process crashes. Relies on having symbols dynamically exported for symbol resolution.

  • void print_backtrace(const char * message)
    Prints out the current backtrace to the console.

  • int capture_backtrace(uintptr_t * counters, std::size_t counter_length)
    Captures a backtrace into the given array. Returns the PC counters, starting at most recent frame, and going up to the limit given.

    Returns the number of frames written, or -1 if there was an error.

  • ResolvedBacktraceSymbol resolve_symbol_at_program_counter(uintptr_t pc)
    Resolves the symbol into a human-readable name at the given program counter. The symbol will be demangled before being returned, if possible.

Declared in “ark/core/codes.hh”:

  • std::string generate_code(size_t digits, size_t base, CodeGenerationFlags flags)
    Generates a new human-readable code with the given number of digits and base. This is essentially a random string which will always be ‘digits’ length. The defaults are generally suitable for human consumption.

    Base can be from between 2 and 62. Digits can be an arbitrary length. A dash will be inserted automatically every 4 characters, up to the final 6 characters. A base36 code with 8 digits might look like ‘7066-5S62’. A base62 code with 6 digits might look like ‘3ahX15’.

  • std::string generate_typical_unique_code()
    This generates a new human-readable code with ’typical’ settings for a random number or reference identifier.

Declared in “ark/core/container.hh”:

  • MapType::const_iterator find_closest_key(const MapType & map, const typename MapType::key_type & key)
    Return an iterator to the closest key in the map.

Declared in “ark/core/demangle.hh”:

  • std::string demangle_symbol(const char * type_name)
    Demangles the given C++ symbol name, making a best effort. Returns a newly-allocated string containing the demangled name. If there is an error demangling, returns the original type name.

  • std::string demangle_symbol()
    Demanges the given C++ symbol, making a best effort. Returns a newly-allocated string containing the demangled name. If there is an error demangling, returns the original type name.

Declared in “ark/core/endian.hh”:

  • constexpr T big_endian_to_native(T value)
    Converts the given big endian value into the native format (big or little endian).

  • constexpr T native_to_big_endian(T value)
    Converts the given native (big or little) value into big endian format.

Declared in “ark/core/environment.hh”:

  • std::optional< std::string > get_environment_variable(const std::string & name)
    Looks up the environment variable with the given name. Returns an empty optional if not found, otherwise, returns a string copy.

  • std::string get_environment_variable_or_default(const char * name, const char * default_value)
    Looks up the environment variable with the given name. Returns the default value if it is not found, otherwise, returns a string copy.

  • std::optional< std::string > get_environment_variable(const char * name)
    Looks up the environment variable with the given name. Returns an empty optional if not found, otherwise, returns a string copy.

Declared in “ark/core/filesystem.hh”:

  • void write_string_to_file(const std::filesystem::path & path, const std::string_view & content, WriteOptions options)
    A helper routine to reliably write a single string out to the given path. This will throw on any error, including an inability to write the full content out to the given path.

     const std::string expected_string = "Hello world! This is a test string!";
    
     write_string_to_file(path, expected_string);
    
     auto roundtrip = read_string_from_file(path);
    
     EXPECT_EQ(expected_string, roundtrip);
    
  • void write_strings_to_file(const std::filesystem::path & path, std::initializer_list< std::string_view > content, WriteOptions options)
    A helper routine to reliably write multiple strings out to the given path, consecutively. This will throw on any error, including an inability to write the full content out to the given path.

     write_strings_to_file(path, {"Hello ", "world!", " This is a test of ", "multiple strings."});
    
     auto roundtrip = read_string_from_file(path);
    
     EXPECT_EQ(roundtrip, "Hello world! This is a test of multiple strings.");
    
  • std::string read_string_from_file(const std::filesystem::path & path)
    A helper routine to reliably read a complete file into a single string. This will throw errors if the read fails for any reason.

     write_string_to_file(path, "Content", WriteOptions::Synchronize);
    
     EXPECT_EQ(read_string_from_file(path), "Content");
    
  • std::string read_string_from_dynamic_file(const std::filesystem::path & path)
    A helper to read a single string from a dynamic file. This assumes the file is ‘shorter’ (ie, something you’d read from /proc) and always changing, so it will always only do a single read(). Further, it doesn’t trust the size of the file reported, and just returns the length of the first read.

  • bool is_path_contained_within_path(const std::filesystem::path & test_path, const std::filesystem::path & root_path)
    Returns true if the given ’test path’ belongs to (is contained within) the specified root path. Handles test paths with ‘..’s inside them.

    For example, ‘abc/def’ is contained within ‘abc’, but ‘abc/../def’ is not.

     EXPECT_TRUE(is_path_contained_within_path("abc/def", "abc"));
     EXPECT_TRUE(is_path_contained_within_path("abc/def/../abc", "abc"));
     EXPECT_FALSE(is_path_contained_within_path("abc/../def", "abc"));
    
  • constexpr WriteOptions operator|(WriteOptions lhs, WriteOptions rhs)
    Operator for adding an option to the list.

  • constexpr WriteOptions operator&(WriteOptions lhs, WriteOptions rhs)
    Operator for adding an option to the list.

  • WriteOptions & operator|=(WriteOptions & lhs, WriteOptions rhs)
    Operator for adding an option to the list.

  • WriteOptions & operator&=(WriteOptions & lhs, WriteOptions rhs)
    Operator for adding an option to the list.

Declared in “ark/core/guid.hh”:

  • bool is_guid(const std::string_view & string)
    Returns true if the given string is likely to be a GUID, false otherwise.

  • std::ostream & operator«(std::ostream & stream, const Guid & guid)
    A stream operator, to make it easier to print these out with cout or in gtest.

Declared in “ark/core/hash.hh”:

  • uint64_t fnv1a_hash(const std::string_view & text)
    Returns a simple FNV1A hash (64-bit) for the given string content. This can be used to generate hashes with a low chance of collision deterministically across platforms.

     EXPECT_EQ(fnv1a_hash(""), 0xcbf29ce484222325ULL);
     EXPECT_EQ(fnv1a_hash("a"), 0xaf63dc4c8601ec8cULL);
     EXPECT_EQ(fnv1a_hash("foobar"), 0x85944171f73967e8ULL);
     EXPECT_EQ(fnv1a_hash("hello"), 0xa430d84680aabd0bULL);
     EXPECT_EQ(fnv1a_hash("hello world"), 0x779a65e7023cd2e7ULL);
     EXPECT_EQ(fnv1a_hash("77kepQFQ8Kl"), 0);
    

Declared in “ark/core/poll.hh”:

  • int poll(struct pollfd * fds, nfds_t nfds, std::chrono::nanoseconds timeout)
    A version of poll() which will take in a C++ std::chrono duration. Otherwise, it behaves identically to poll(), with one exception, in that it will honor sub-millisecond level wait times (currently via using ppoll internally).

     const EventCondition condition;
    
     struct pollfd pfd;
    
     pfd.fd = condition.native_handle();
     pfd.events = POLLIN;
     pfd.revents = 0;
    
     //
     // Not signaled, should return zero.
     //
    
     auto result = poll(&pfd, 1, std::chrono::nanoseconds{0});
    
     EXPECT_EQ(pfd.revents, 0);
     EXPECT_EQ(result, 0);
    
     //
     // Signal, we should now return 1.
     //
    
     condition.notify();
    
     result = poll(&pfd, 1, std::chrono::seconds{60});
    
     EXPECT_EQ(pfd.revents, POLLIN);
     EXPECT_EQ(result, 1);
    
     //
     // Clear, should go back to zero.
     //
    
     condition.clear();
    
     result = poll(&pfd, 1, std::chrono::nanoseconds{0});
    
     EXPECT_EQ(pfd.revents, 0);
     EXPECT_EQ(result, 0);
    

Declared in “ark/core/round.hh”:

  • double round_to_decimal_place(double value, int decimal_places)
    Rounds the original value to the nearest value with the given number of decimal places.

     EXPECT_NEAR(round_to_decimal_place(3.14159, 0), 3.0, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(3.14159, 1), 3.1, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(3.14159, 2), 3.14, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(3.14159, 3), 3.142, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(3.14159, 4), 3.1416, 0.0000001);
    
     EXPECT_NEAR(round_to_decimal_place(186282.159, 0), 186282, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(186282.159, 1), 186282.2, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(186282.159, 2), 186282.16, 0.0000001);
     EXPECT_NEAR(round_to_decimal_place(186282.159, 3), 186282.159, 0.0000001);
    
  • Type round_to_nearest(Type original, Type multiple)
    Rounds the original value to the nearest multiple of the ‘multiple’ parameter.

     EXPECT_EQ(round_to_nearest(70, 100), 100);
     EXPECT_EQ(round_to_nearest(70, 200), 0);
     EXPECT_EQ(round_to_nearest(150, 200), 200);
     EXPECT_EQ(round_to_nearest(120, 200), 200);
     EXPECT_EQ(round_to_nearest(-250, 200), -200);
     EXPECT_EQ(round_to_nearest(-150, 200), -200);
     EXPECT_EQ(round_to_nearest(20, 100), 0);
     EXPECT_EQ(round_to_nearest(20, 200), 0);
     EXPECT_EQ(round_to_nearest(55, 60), 60);
     EXPECT_EQ(round_to_nearest(62, 60), 60);
     EXPECT_EQ(round_to_nearest(-40, 60), -60);
    
  • Type round_up_to_multiple(Type original, Type multiple)
    Rounds the original value up to the next multiple of the ‘multiple’ parameter.

     EXPECT_EQ(round_up_to_multiple(3, 32), 32);
     EXPECT_EQ(round_up_to_multiple(31, 32), 32);
     EXPECT_EQ(round_up_to_multiple(32, 32), 32);
     EXPECT_EQ(round_up_to_multiple(33, 32), 64);
     EXPECT_EQ(round_up_to_multiple(63, 32), 64);
     EXPECT_EQ(round_up_to_multiple(65, 32), 96);
    
     EXPECT_EQ(round_up_to_multiple(65, 10), 70);
     EXPECT_EQ(round_up_to_multiple(65, 20), 80);
     EXPECT_EQ(round_up_to_multiple(65, 1000), 1000);
     EXPECT_EQ(round_up_to_multiple(0, 1000), 0);
    
     EXPECT_EQ(round_up_to_multiple(-10, 1000), 0);
     EXPECT_EQ(round_up_to_multiple(-1010, 1000), -1000);
    
     EXPECT_EQ(round_up_to_multiple(71, 4096), 4096);
    
     EXPECT_EQ(round_up_to_multiple(65, -32), 64);
    

Declared in “ark/core/signal.hh”:

  • void install_interrupt_signal_handler(std::function< void()> callback)
    Allows you to install a signal handler that is invoked if the executable receives an interrupt signal (such as SIGINT).

  • void clear_interrupt_signal_handler()
    Clears the interrupt signal handler. Typically used during testing to reset state.

  • std::string signal_to_string(int32_t signal_number)
    Translates the given signal number to a string, handling re-entrancy.

Declared in “ark/core/sleep.hh”:

  • bool sleep_for_and_check(std::chrono::nanoseconds sleep_duration, std::chrono::nanoseconds test_duration, const std::function< bool()> & callback)
    Sleeps for the given duration, waking up periodically to execute your callback. If the callback returns true, continues sleeping, otherwise, exits the loop early.

    Returns false if we woke up early, or true otherwise.

Declared in “ark/core/strerror.hh”:

  • std::string errno_to_string(int desired_errno)
    Convert the given errno code into a string, safely. This will allocate memory, but is reentrant.

  • void errno_to_string(int desired_errno, char * buffer, size_t buffer_length)
    Convert the given errno code into a string, safely, outputting to the given buffer. Avoids an allocation.

  • std::string last_errno_as_string()
    Thread safe method to return a conversion from errno to a string. This will allocate memory.

Declared in “ark/core/system.hh”:

  • std::string get_hostname()
    Returns the hostname of this system.

  • std::string get_hardware_architecture()
    Returns the hardware architecture of the running system.

  • std::string get_this_process_name()
    Returns the process name of this running binary. This is typically the short name.

  • std::string get_this_process_invocation_name()
    Returns the process name of this running binary. This is typically the full path to the binary (ie, argv[0]).

Declared in “ark/core/thread.hh”:

  • void set_this_thread_name(const std::string & name)
    Sets the thread name to the given string safely. On some platforms, the thread name is limited to 15 characters this function will truncate for you.

  • std::string get_this_thread_name()
    Returns this thread’s name, if available. May be an empty string.

  • int32_t get_this_thread_id()
    Returns this thread’s identifier (ie, equivalent to the gettid() syscall, which may not be available).

  • void set_this_thread_priority(ThreadScheduler scheduler, int priority)
    Sets the current thread’s priority and preferred scheduler. This is largely operating-system specific. Throws if setting fails.

  • void set_this_thread_affinity(const std::vector< bool > & processors)
    Sets the current thread’s processor affinity, based on the list of booleans provided. The first entry in the list corresponds to processor 0, the second to processor 1, and so on. If the boolean is set, the thread can be scheduled on that processor.

  • void sleep_random_duration(std::chrono::milliseconds duration)
    Sleep for a random interval. This will sleep between 1ms and the given number of milliseconds, choosing a random number from a uniform distribution.

Declared in “ark/core/throw.hh”:

  • std::string get_last_throw_backtrace()
    Returns a printable backtrace that was last captured during a throw event, if any. If ARK_WRAP_EXCEPTIONS is disabled, this will return an empty string.

  • void print_last_throw_backtrace_if_available(const char * message)
    If the last throw backtrace is available, this will print the given message out, and then the backtrace. If not, this routine does nothing.

Declared in “ark/core/variant.hh”:

  • const std::type_info & variant_held_type(const Variant & input)
    Returns the typeinfo of the selected type in the given variant.

  • constexpr std::size_t variant_index()
    Used to return the index of a specific type in a variant. In other words, if you want to know the index of ‘double’ in variant<int, double>, it will return ‘1’. ‘int’ would be ‘0’.