libcpr Manual

Introduction

libcpr is a public domain backport of the core data structures and algorithms from the C++11 standard library to C.

Features

  • Implements a straightforward mapping from C++ to C, with consistent naming.
  • No runtime dependencies other than C99 and the system’s C++ standard library.
  • No build prerequisites beyond the Autotools toolchain and a C++11 compiler.
  • Compatible with Clang and GCC, or indeed any standard C++11 implementation.
  • Plays nice with others: all exported symbols are prefixed with cpr_.
  • 100% free and unencumbered public domain software, usable in any context and for any purpose.

Motivation

The C standard library is severely deficient in useful data structures essential to modern programming practice. Consequently, most non-trivial C programs and shared libraries include one-off implementations of even the most elementary data structures such as dynamic arrays and hash tables. This harms programmer productivity, bloats the sizes of binaries, wastes machine resources, and inevitably introduces unnecessary bugs–including security vulnerabilities.

The alternative to rolling your own data structures has thus far been to pull in a large, all-purpose library dependency such as GLib. The problem with this approach is that you just wanted a hash table, but you got the kitchen sink with an XML parser thrown in for good measure. These all-purpose libraries have a huge footprint and can be difficult to install, ensuring that your potential user base will prefer competing projects who do roll their own data structures.

libcpr is a new take on an old problem. Given that every modern desktop and server system today is guaranteed to already have not merely the C standard library but also the C++ standard library, libcpr provides the until-now missing glue to access that latter library from pure C. The C++ standard library contains the basic data structures and algorithms needed for most common programming tasks, and adds no bloat since it’s already installed on the system regardless.

Current Status

At present, vectors and strings are partially implemented. Other sequence containers (list, deque) and associative containers (set, multiset, map, multimap) are planned but not yet implemented.

Installation

Installation on Linux

This section describes how to build and install libcpr on Linux platforms.

From the source repository

$ git clone https://github.com/dryproject/libcpr.git
$ cd libcpr
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

From a source tarball

$ ./configure
$ make
$ sudo make install
$ sudo ldconfig

On Debian or Ubuntu Linux

For now, use the tarball instructions (see previous subsection) to install.

On Fedora or RHEL

For now, use the tarball instructions (see previous subsection) to install.

On Gentoo Linux

For now, use the tarball instructions (see previous subsection) to install.

Installation on FreeBSD

This section describes how to build and install libcpr on FreeBSD.

From the source repository

$ git clone https://github.com/dryproject/libcpr.git
$ cd libcpr
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

From a source tarball

$ ./configure
$ make
$ sudo make install

From FreeBSD Ports

libcpr is not yet included in the FreeBSD Ports collection.

For now, use the tarball instructions (see previous subsection) to install.

Installation on Mac OS X

This section describes how to build and install libcpr on Mac OS X.

Prerequisites

To build and install libcpr from source on Mac OS X, you need an up-to-date toolchain that supports the C++11 standard; that is, you need a recent enough C++ compiler and a C++11-conformant standard library. This means either Clang 3.0+ with libc++, or GCC 4.7+ with libstdc++.

Apple’s free Xcode 4.6+ developer tools for Mac OS X 10.8 (Mountain Lion) and 10.7 (Lion) include recent enough Clang and libc++ releases that will work. You don’t need the full Xcode installation, only the Command Line Tools for Xcode.

On Mac OS X 10.6 (Snow Leopard), 10.5 (Leopard), or 10.4 (Tiger), you will need to first manually upgrade your toolchain to support the C++11 standard before you can compile libcpr. That means installing either GCC 4.7 or Clang 3.2 and libc++ from source, a topic beyond the scope of this manual.

From the source repository

$ git clone https://github.com/dryproject/libcpr.git
$ cd libcpr
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

From a source tarball

$ ./configure
$ make
$ sudo make install

Using Homebrew

libcpr is not yet officially included in the Homebrew packaging system.

However, the etc/homebrew directory in the libcpr source code repository includes a Homebrew formula, and you can therefore use Homebrew to quickly and easily install libcpr, as follows:

$ brew install --HEAD \
  https://raw.github.com/dryproject/libcpr/master/etc/homebrew/libcpr.rb

Using MacPorts

libcpr is not yet officially included in the MacPorts packaging system.

However, the etc/macports directory in the libcpr source code repository includes a MacPorts portfile. If you have a local portfile repository set up, you can copy over the portfile, re-run portindex, and then install as follows:

$ sudo port install libcpr

Otherwise, use the tarball instructions (see previous subsection) to install.

Using Fink

libcpr is not yet included in the Fink packaging system.

For now, use the tarball instructions (see previous subsection) to install.

Installation on MinGW

This section describes how to build and install libcpr on MSYS/MinGW.

From the source repository

$ git clone https://github.com/dryproject/libcpr.git
$ cd libcpr
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

From a source tarball

$ ./configure
$ make
$ sudo make install

Configuration Options

This section documents libcpr-specific command-line options that may be passed to the ./configure script to customize the build of the library.

C++ Standard Library

The following options can be used to specify the C++ standard library implementation to use for the build. By default, when this option is not given, the system C++ standard library is used. On Unix platforms based on the GNU toolchain, the system library is libstdc++.

--with-stdlib=libstdc++
Use the libstdc++ standard library from the GCC project. This is the default with both the GCC and Clang compilers.
--with-stdlib=libc++
Use the libc++ standard library from the LLVM project. You almost certainly want to specify this on recent versions of FreeBSD and Mac OS X, and you may wish to use it on Linux if it is available.

Note

When both are available, the choice between libstdc++ and libc++ is easy: use libc++ due to its comprehensive C++11 support, its favorable performance and memory footprint characteristics, and its permissive licensing.

Debugging Support

The following options are meant primarily for libcpr developers:

--enable-debug
Build with debugging support. Debugging is disabled by default.
--disable-assert
Turn off assertions specifically. Assertions are disabled by default.

Advanced Customization

You should not ordinarily need to use the following options. They are provided for special situations such as e.g. compiling a minimal static library version of libcpr for an embedded platform.

--disable-list
Do not include the list module. The module is included by default.
--disable-map
Do not include the map module. The module is included by default.
--disable-set
Do not include the set module. The module is included by default.
--disable-string
Do not include the string module. The module is included by default.
--disable-vector
Do not include the vector module. The module is included by default.

Note

An alternative to building a reduced-functionality version of libcpr is to just copy over into your project those libcpr header and implementation files you require. They are all in the public domain.

Usage

Macros

This chapter describes the C/C++ preprocessor macros that enable the customization of your use of libcpr.

CPR_ABBREV

If defined, enables abbreviated type and function names without the cpr_ prefix. To use these names, CPR_ABBREV must be defined before including any of the cpr/*.h header files, as follows:

#define CPR_ABBREV
#include <cpr.h>
CPR_UNSAFE

If defined, enables the use of stack allocation for libcpr data structures. This is more efficient than heap allocation, but “unsafe” since it will break the ABI should the structure sizes change in a future libcpr release.

#define CPR_UNSAFE
#include <cpr.h>

Alternatively and equivalently, just include the <cpr/unsafe.h> header directly if you prefer the following style:

#include <cpr.h>
#include <cpr/unsafe.h>

Note

When the <cpr/unsafe.h> header is included, the header defines CPR_UNSAFE if it has not yet been defined. This ensures reliable conditionalization of code based on #ifdef CPR_UNSAFE, regardless of whether the user or the header originally defined this preprocessor symbol.

API Reference

Header <cpr.h>

Note

For convenience, <cpr.h> includes all other <cpr/*.h> header files. This is the case regardless of whether you have disabled building a particular module when running ./configure to configure your build. If you’ve disabled particular modules in such a manner, you should not include <cpr.h> in your project’s source files; rather, you should explicitly include only the header files for the modules that you actually use.

Header <cpr/error.h>

cpr_error_trigger()

Synopsis
#include <cpr/error.h>
Description
Parameters
Return Value
Errors

This function sets errno to the value given in the error_code argument.

Complexity

Constant.

Example
cpr_error_trigger(__func__, ENOMEM, "out of memory");

Header <cpr/feature.h>

cpr_feature_exists()

Synopsis
#include <cpr/feature.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

Header <cpr/generic.h>

Header <cpr/list.h>

cpr_list_alloc()

Synopsis
#include <cpr/list.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_list_free()

Synopsis
#include <cpr/list.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_list_sizeof

Synopsis
#include <cpr/list.h>
Description
Example

TODO

cpr_list_t

Synopsis
#include <cpr/list.h>
Description
Example

TODO

Header <cpr/map.h>

cpr_map_alloc()

Synopsis
#include <cpr/map.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_map_free()

Synopsis
#include <cpr/map.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_map_sizeof

Synopsis
#include <cpr/map.h>
Description
Example

TODO

cpr_map_t

Synopsis
#include <cpr/map.h>
Description
Example

TODO

Header <cpr/module.h>

cpr_module_exists()

Synopsis
#include <cpr/module.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

Header <cpr/set.h>

cpr_set_alloc()

Synopsis
#include <cpr/set.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_set_free()

Synopsis
#include <cpr/set.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_set_sizeof

Synopsis
#include <cpr/set.h>
Description
Example

TODO

cpr_set_t

Synopsis
#include <cpr/set.h>
Description
Example

TODO

Header <cpr/string.h>

cpr_string()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_alloc()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_capacity()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_empty()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_free()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_length()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_max_size()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_npos

Synopsis
#include <cpr/string.h>
Description
Example

TODO

cpr_string_size()

Synopsis
#include <cpr/string.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_string_sizeof

Synopsis
#include <cpr/string.h>
Description
Example

TODO

cpr_string_t

Synopsis
#include <cpr/string.h>
Description
Example

TODO

Header <cpr/unsafe.h>

cpr_list_alloca()

Synopsis
#include <cpr/unsafe.h>
#include <cpr/list.h>
cpr_list_t* cpr_list_alloca(void)
Description

This is a macro that translates into the following code:

alloca(cpr_list_sizeof)
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_map_alloca()

Synopsis
#include <cpr/unsafe.h>
#include <cpr/map.h>
cpr_map_t* cpr_map_alloca(void)
Description

This is a macro that translates into the following code:

alloca(cpr_map_sizeof)
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_set_alloca()

Synopsis
#include <cpr/unsafe.h>
#include <cpr/set.h>
cpr_set_t* cpr_set_alloca(void)
Description

This is a macro that translates into the following code:

alloca(cpr_set_sizeof)
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_string_alloca()

Synopsis
#include <cpr/unsafe.h>
#include <cpr/string.h>
cpr_string_t* cpr_string_alloca(void)
Description

This is a macro that translates into the following code:

alloca(cpr_string_sizeof)
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_alloca()

Synopsis
#include <cpr/unsafe.h>
#include <cpr/vector.h>
cpr_vector_t* cpr_vector_alloca(void)
Description

This is a macro that translates into the following code:

alloca(cpr_vector_sizeof)
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

Header <cpr/vector.h>

cpr_vector()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_alloc()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_at()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_back()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_capacity()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_clear()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_data()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_dispose()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_empty()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_free()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_front()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_init()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_init_with_capacity()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_pop_back()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_push_back()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_reserve()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

TODO

Example

TODO

cpr_vector_size()

Synopsis
#include <cpr/vector.h>
Description
Parameters
Return Value
Errors
Complexity

Constant.

Example

TODO

cpr_vector_sizeof

Synopsis
#include <cpr/vector.h>
Description
Example

TODO

cpr_vector_t

Synopsis
#include <cpr/vector.h>
Description
Example

TODO

Header <cpr/version.h>

cpr_version_string

Synopsis
#include <cpr/version.h>
Description
Example

TODO

CPR_VERSION_STRING

CPR_VERSION_STRING

CPR_VERSION_MAJOR

CPR_VERSION_MAJOR

CPR_VERSION_MINOR

CPR_VERSION_MINOR

CPR_VERSION_PATCH

CPR_VERSION_PATCH

API and ABI Versioning

libcpr uses a three-level “X.Y.Z” API versioning scheme, as follows:

  • Patch versions (e.g., 0.1.**3**, 1.0.**1**, 1.2.**8**).
  • Minor versions (e.g., 0.**4**.0, 1.**1**.0).
  • Major versions.

Frequently Asked Questions (FAQ)

FAQ: General Questions

This section collects answers to frequently-asked general questions regarding the libcpr project.

Q: What is libcpr?

A: libcpr is a public domain backport of the core data structures and algorithms from the C++11 standard library to C.

The library is implemented as a C wrapper around C++11 functionality. It therefore requires a C++11 compiler to build, but the resulting library binaries can be used from any C program without any C++ dependencies.

For more particulars, take a look at the Introduction chapter.

Q: Why is it named libcpr instead of something else?

A: The name libcpr has two parallel and congruent origins:

  1. The project originally started out being called C′ (as in, C-prime), with a rather larger scope than at present, before being rebooted back to basics.
  2. The library could be considered an effort to administer CPR to the venerable C language.

Q: Which version of the C standard does the library require?

A: The project currently targets C99, loosely defined. For example, some of the libcpr function prototypes require the <stdbool.h> standard header introduced in C99.

That said, it is perfectly feasible to use libcpr in pre-C99 projects by explicitly providing for the handful of C99 facilities that the library requires.

Q: How portable is the library?

A: The code base is written in standard, clean, and modern C++11, and should be highly portable to conforming C++ compilers and standard libraries.

Q: Which C++ compilers does the library build with?

A: At present, the library has been successfully built and tested with the following compilers and platforms:

Platform Compiler Standard Library
Fedora 18
Clang 3.2
GCC 4.7.x
libc++
libstdc++
Gentoo Linux
Clang 3.2
Clang 3.2
GCC 4.6.3
libc++
libstdc++
libstdc++
Mac OS X 10.7.5
Xcode 4.6.1 Clang 425.0.27
libc++
Ubuntu 12.10
Clang 3.2 PPA
Clang 3.2 PPA
GCC 4.7.2
libc++
libstdc++
libstdc++
Ubuntu 12.04
Clang 3.2 SVN
GCC 4.6.3
libstdc++
libstdc++

Note

GCC releases older than 4.5.x will not suffice to build libcpr, nor will Clang releases older than 3.0.

FAQ: Installation Questions

This section provides answers and solutions to common installation-related questions and problems.

Q: How do I build the library using libc++ instead of libstdc++?

A: TODO

$ ./configure --with-stdlib=libc++   # sets CXXFLAGS and LDFLAGS

Q: How do I fix error: A compiler with support for C++11 language features is required.?

A: This error means that your autodetected C++ compiler does not support the C++11 standard; most likely, the ./configure found an older version of GCC, such as GCC 4.2 on Mac OS X systems.

If you have a newer compiler available on your system, set the CC and CXX environment variables accordingly. For example, to use Clang, you would configure the libcpr build as follows:

$ CC=clang CXX=clang++ ./configure

If you don’t have a C++11 compiler, you will need to obtain one to build libcpr. Please refer to the Installation chapter for directions.

Q: How do I fix fatal error: 'system_error' file not found?

A: This error means that your C++ compiler is using a pre-C++11 standard library, most likely an old version of the libstdc++ standard library that ships with GCC.

The problem here is that for reasons of backwards compatibility, Clang (the C/C++ compiler on Mac OS X) by default always uses the GCC 4.2-era libstdc++ standard library implementation, which predates the C++11 standard and does not support most C++11 features. This is the case regardless of whether you specify the -std=c++11 flag when compiling.

If you’re on Mac OS X 10.8 (Mountain Lion) or 10.7 (Lion), the fix is simple: just make sure that the CXXFLAGS and LDFLAGS environment variables also include the flag -stdlib=libc++. This will make Clang use the C++11-conformant libc++ standard library implementation instead of the ancient libstdc++ still shipped by Apple. The best way to ensure this is to configure the libcpr build as follows:

$ ./configure --with-stdlib=libc++   # sets CXXFLAGS and LDFLAGS

For more information, refer to the Configuration Options section.

However, if you’re on Mac OS X 10.6 (Snow Leopard), 10.5 (Leopard), or 10.4 (Tiger), the aforementioned in and of itself will not help you since Apple did not yet ship libc++ with these earlier operating system releases. You will therefore need to manually upgrade your toolchain for C++11 support. Please refer to the Installation on Mac OS X section for particulars.

FAQ: Technical Questions

This section collects answers to frequently-asked miscellaneous technical questions regarding the libcpr library.

Q: Why are all exported symbols prefixed with cpr_?

A: TODO

Q: Is the library thread-safe?

A: TODO

Q: How can I detect the library using autoconf or pkg-config?

A: TODO

Q: Why are preconditions enforced using assertions?

A: TODO

Q: Why does the build fail with the error ‘std::string’ has no member named ‘pop_back’?

A: This indicates that your C++ standard library does not support the C++11 standard. This is the case for example with the version of libstdc++ shipped with GCC 4.6. To build libcpr successfully, you will need to upgrade your C++ compiler and/or standard library.

Design Notes

Design Philosophy

  • Catches all C++ exceptions and translates them into C error codes.
  • Carefully differentiates logic errors, runtime errors, and fatal errors.

Naming Conventions

The naming conventions and indeed symbol the symbol names themselves are closely patterned after those of the C++ standard library. This is most evident when perusing the cross-reference.

Since C does not support function overloading, C++ standard library methods which provide multiple overloads are differentiated in libcpr by suffixing the corresponding function names with a disambiguating string, usually a type name. For example std::string::append() provides multiple overloads; the corresponding libcpr functions are provided as cpr_string_append_char() for a character argument, cpr_string_append_str() for a C string argument, and so on.

Module Boundaries

Memory Management

All constructor functions return pointers to opaque structures allocated on the program heap using the system’s standard calloc() facility. The library provides corresponding deallocation functions to destruct and free these pointers.

Given that all object pointers are to opaque structures, no direct access to any structure fields is permitted or afforded; all access is procedural. This encapsulation facilitates and ensures ABI stability as the library evolves.

Initialization and Finalization

Error Handling

Iterator Operations

TODO

Emplacement Operations

Since the elements stored by libcpr containers are void* pointers, the library does not provide any analogues of the emplacement operations from the C++11 standard library.

That said, libcpr containers can also be (ab)used to directly store machine-word-sized value types, such as integers or floating-point numbers; in such a case, the ordinary insertion operations work equivalently to emplacement operations with the help of a little type casting:

/* Store the integer 42 in a vector directly: */
cpr_vector_push_back(vector, (void*)(long)42);

Object Layout

While all libcpr structure types are opaque to the user (meaning that no direct access to their internals is afforded), a design guarantee that can be relied on is that any pointer to a libcpr object in fact also corresponds to a pointer to the underlying C++ object that the type is implemented with.

For example, the opaque cpr_vector_t type is defined as follows internally to the library:

typedef struct cpr_vector {
  std::vector<void*> data;
  void (*erase_hook)(void*);
} cpr_vector_t;

Thus, a cpr_vector_t* pointer in user C code is equivalent to a std::vector<void*>* pointer or a std::vector<void*>& reference in C++ code.

This facilitates C++ interoperability by ensuring that libcpr objects can be passed as arguments to C++ functions that expect native C++ standard library types. In particular, this is helpful for working with functions that expect an std::string argument.

The following table explains the relationship between libcpr object types and their corresponding internal C++ implementations:

C type C++ type
cpr_list_t* std::list<void*>&
cpr_map_t* std::map<void*, void*>&
cpr_set_t* std::set<void*>&
cpr_string_t* std::string& (aka std::basic_string<char>&)
cpr_vector_t* std::vector<void*>&

Warning

You must not let foreign code deallocate any libcpr object, as that might not correctly destruct other fields of the object for types that contain additional fields past the first field that holds the internal C++ implementation. Similarly, doing so would not invoke the erase hook on the pointer of each element in a container object. Destruction and deallocation must be done using the libcpr API only.

Contributing

This chapter explains how you can contribute to the ongoing development of the libcpr project.

Reporting Bugs

Please report bugs to the issue tracker at: https://github.com/dryproject/libcpr/issues.

Contributing Patches

If you wish to contribute a patch, please open a pull request at: https://github.com/dryproject/libcpr/pulls

Contribution Guidelines

  • Do your best to adhere to the existing coding conventions and idioms.
  • Don’t use hard tabs, and don’t leave trailing whitespace on any line. Before committing, run git diff --check to make sure of this.
  • Do document every function you add using Doxygen annotations. Read the tutorial or just look at the existing code for examples.
  • Don’t touch the VERSION file. If you need to change it, do so on your private branch only.
  • Do feel free to add yourself to the CREDITS file and the corresponding list in the the README. Alphabetical order applies.
  • Don’t touch the AUTHORS file. If your contributions are significant enough, be assured we will eventually add you in there.

Project Scope

Before spending much time writing a large patch set that adds all the features that the library ostensibly is missing, please take a moment to consider whether the desired functionality truly fits within the stated scope of the project.

libcpr has a clear and concise scope defined by the project’s tagline of backporting the core of the C++11 standard library to C.

This means that libcpr is, and is intended to remain, largely just a C wrapper for functionality present in the C++ standard library. Other than basic metadata about the shared library itself (information about features, modules, and the library version), plus hooks for error handling and memory management, the bulk of the library is structured so as to correspond one-to-one to the ported C++ standard library functionality.

The following are some examples of patches that are outside the project scope and that therefore would not ordinarily be considered for inclusion into libcpr:

  • Data structures or algorithms not present in the C++ standard library.
  • Operating system-specific functionality beyond the standard library.

Coding Conventions

Header Files

/* This is free and unencumbered software released into the public domain. */

#ifndef CPR_WIDGET_H
#define CPR_WIDGET_H

/**
 * @file
 *
 * Module description goes here.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <stdbool.h> /* for bool */

/**
 * Function description goes here.
 */
bool cpr_widget_supported(const char* widget_type);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* CPR_WIDGET_H */

Donations

If you found this software useful and would like to encourage its maintenance and further development, please consider making a donation to the Bitcoin wallet address 1FxcaWrxZ1sVCdbw6ZC8eM6BhwPVnKy5fZ.

Release Notes

There have been no official releases of libcpr as yet.

License

libcpr is 100% free and unencumbered public domain software.

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>

Cross Reference

C++11 Cross Reference

<algorithm>

See also

C++ Reference: <algorithm> header
Documentation for the std::* algorithms.

<bitset>

See also

C++ Reference: <bitset> header
Documentation for the std::bitset interface.

<dequeue>

See also

C++ Reference: <dequeue> header
Documentation for the std::dequeue interface.

<list>

See also

C++ Reference: <list> header
Documentation for the std::list interface.

<map>

See also

C++ Reference: <map> header
Documentation for the std::map interface.

<set>

See also

C++ Reference: <set> header
Documentation for the std::set interface.

<string>

C++11 libcpr
std::string cpr_string_t
std::string::string() cpr_string()
std::string::~string() cpr_string_free()
std::string::append()
cpr_string_append_char()
cpr_string_append_str()
cpr_string_append_string()
std::string::assign()
cpr_string_assign_char()
cpr_string_assign_str()
cpr_string_assign_string()
std::string::at() cpr_string_at()
std::string::back() cpr_string_back()
std::string::begin() N/A [1]
std::string::capacity() cpr_string_capacity()
std::string::cbegin() N/A [1]
std::string::cend() N/A [1]
std::string::clear() cpr_string_clear()
std::string::compare() cpr_string_compare()
std::string::copy() cpr_string_copy()
std::string::crbegin() N/A [1]
std::string::crend() N/A [1]
std::string::c_str() cpr_string_data()
std::string::data() cpr_string_data()
std::string::empty() cpr_string_empty()
std::string::end() N/A [1]
std::string::erase() cpr_string_erase()
std::string::find()
cpr_string_find_char()
cpr_string_find_str()
cpr_string_find_string()
std::string::find_first_not_of() N/A
std::string::find_first_of() N/A
std::string::find_last_not_of() N/A
std::string::find_last_of() N/A
std::string::front() cpr_string_front()
std::string::get_allocator() N/A
std::string::insert()
cpr_string_insert_char()
cpr_string_insert_str()
cpr_string_insert_string()
std::string::length() cpr_string_length()
std::string::max_size() cpr_string_max_size()
std::string::npos() cpr_string_npos()
std::string::operator+=()
cpr_string_append_char()
cpr_string_append_str()
cpr_string_append_string()
std::string::operator=()
cpr_string_assign_char()
cpr_string_assign_str()
cpr_string_assign_string()
std::string::operator[]() cpr_string_at()
std::string::pop_back() cpr_string_pop_back()
std::string::push_back() cpr_string_push_back()
std::string::rbegin() N/A [1]
std::string::rend() N/A [1]
std::string::replace() N/A
std::string::reserve() cpr_string_reserve()
std::string::resize() cpr_string_resize()
std::string::rfind()
cpr_string_rfind_char()
cpr_string_rfind_str()
cpr_string_rfind_string()
std::string::shrink_to_fit() cpr_string_shrink_to_fit()
std::string::size() cpr_string_size()
std::string::substr() cpr_string_substr()
std::string::swap() cpr_string_swap()

Footnotes

[1](1, 2, 3, 4, 5, 6, 7, 8) Iterator operations are not supported.

See also

C++ Reference: <string> header
Documentation for the std::string interface.

<vector>

C++11 libcpr
std::vector cpr_vector_t
std::vector::vector() cpr_vector()
std::vector::~vector() cpr_vector_free()
std::vector::assign() N/A
std::vector::at() cpr_vector_at()
std::vector::back() cpr_vector_back()
std::vector::begin() N/A [2]
std::vector::capacity() cpr_vector_capacity()
std::vector::cbegin() N/A [2]
std::vector::cend() N/A [2]
std::vector::clear() cpr_vector_clear()
std::vector::crbegin() N/A [2]
std::vector::crend() N/A [2]
std::vector::data() cpr_vector_data()
std::vector::emplace() N/A [3]
std::vector::emplace_back() N/A [3]
std::vector::empty() cpr_vector_empty()
std::vector::end() N/A [2]
std::vector::erase() N/A
std::vector::front() cpr_vector_front()
std::vector::get_allocator() N/A
std::vector::insert() N/A
std::vector::max_size() N/A
std::vector::operator=() N/A
std::vector::operator[]() cpr_vector_at()
std::vector::pop_back() cpr_vector_pop_back()
std::vector::push_back() cpr_vector_push_back()
std::vector::rbegin() N/A [2]
std::vector::rend() N/A [2]
std::vector::reserve() cpr_vector_reserve()
std::vector::resize() N/A
std::vector::shrink_to_fit() N/A
std::vector::size() cpr_vector_size()
std::vector::swap() N/A

Footnotes

[2](1, 2, 3, 4, 5, 6, 7, 8) Iterator operations are not supported. Access the vector elements with cpr_vector_at(), bounded by cpr_vector_size(); or, alternatively, directly through the pointer returned by cpr_vector_data().
[3](1, 2) Emplacement operations are not supported. Use cpr_vector_insert() or cpr_vector_push_back().

See also

C++ Reference: <vector> header
Documentation for the std::vector interface.

GLib 2.x Cross Reference

GHashTable

See also

GLib Reference Manual: Hash Tables
Documentation for the GHashTable interface.

GList

See also

GLib Reference Manual: Doubly-Linked Lists
Documentation for the GList interface.

GPtrArray

GLib 2.x libcpr
GPtrArray cpr_vector_t
g_ptr_array_add() cpr_vector_push_back()
g_ptr_array_foreach() TODO: cpr_vector_for_each()
g_ptr_array_free() cpr_vector_free()
g_ptr_array_index() cpr_vector_at()
g_ptr_array_new() cpr_vector()
g_ptr_array_new_full() cpr_vector_init_with_capacity()
g_ptr_array_new_with_free_func() cpr_vector_init()
g_ptr_array_ref() N/A
g_ptr_array_remove() TODO
g_ptr_array_remove_fast() TODO
g_ptr_array_remove_index_fast() TODO
g_ptr_array_remove_index() TODO
g_ptr_array_remove_range() TODO
g_ptr_array_set_free_func() TODO: cpr_vector_hook()
g_ptr_array_set_size() TODO: cpr_vector_resize()
g_ptr_array_sized_new() cpr_vector_init_with_capacity()
g_ptr_array_sort() TODO: cpr_vector_sort()
g_ptr_array_sort_with_data() N/A
g_ptr_array_unref() N/A

See also

GLib Reference Manual: Pointer Arrays
Documentation for the GPtrArray interface.

GQueue

See also

GLib Reference Manual: Double-ended Queues
Documentation for the GQueue interface.

GString

GLib 2.x libcpr
GString cpr_string_t
GString.str TODO: cpr_string_data()
GString.len cpr_string_size()
GString.allocated_len cpr_string_capacity()
g_string_append() TODO: cpr_string_append_str()
g_string_append_c() TODO: cpr_string_append_char()
g_string_append_len() TODO: cpr_string_append_str()
g_string_append_printf() N/A
g_string_append_unichar() N/A
g_string_append_uri_escaped() N/A
g_string_append_vprintf() N/A
g_string_assign() TODO: cpr_string_assign_str()
g_string_down() N/A
g_string_equal() TODO: cpr_string_equal()
g_string_erase() TODO: cpr_string_erase()
g_string_free() TODO: cpr_string_free()
g_string_free_to_bytes() N/A
g_string_hash() TODO: cpr_string_hash()
g_string_insert() TODO: cpr_string_insert_str()
g_string_insert_c() TODO: cpr_string_insert_char()
g_string_insert_len() TODO: cpr_string_insert_str()
g_string_insert_unichar() N/A
g_string_new() cpr_string()
g_string_new_len() TODO
g_string_overwrite() TODO: cpr_string_replace()
g_string_overwrite_len() TODO: cpr_string_replace()
g_string_prepend() TODO: cpr_string_prepend_str()
g_string_prepend_c() TODO: cpr_string_prepend_char()
g_string_prepend_len() TODO: cpr_string_prepend_str()
g_string_prepend_unichar() N/A
g_string_printf() TODO
g_string_set_size() TODO: cpr_string_resize()
g_string_sized_new() TODO: cpr_string_init_with_capacity()
g_string_sprintf() TODO
g_string_sprintfa() TODO
g_string_truncate() TODO: cpr_string_resize()
g_string_up() N/A
g_string_vprintf() TODO

See also

GLib Reference Manual: Strings
Documentation for the GString interface.

GTree

See also

GLib Reference Manual: Balanced Binary Trees
Documentation for the GTree interface.

Bstrlib Cross Reference

Bstrlib libcpr
bstring cpr_string_t
bstring.mlen cpr_string_capacity()
bstring.slen cpr_string_size()
bstring.data N/A
balloc() N/A
ballocmin() N/A
bassign() N/A
bassignblk() N/A
bassigncstr() N/A
bassignformat() N/A
bassignmidstr() N/A
bcatblk() N/A
bcatcstr() N/A
bchar() N/A
bchare() N/A
bconcat() N/A
bconchar() N/A
bcstrfree() N/A
bdata() N/A
bdatae() N/A
bdataofs() N/A
bdataofse() N/A
bdelete() N/A
bdestroy() N/A
bfindreplace() N/A
bfindreplacecaseless() N/A
bformat() N/A
bformata() N/A
bfromcstr() cpr_string()
bfromcstralloc() N/A
binchr() N/A
binchrr() N/A
binsert() N/A
binsertch() N/A
binstr() N/A
binstrcaseless() N/A
binstrr() N/A
binstrrcaseless() N/A
biseq() N/A
biseqcaseless() N/A
biseqcstr() N/A
biseqcstrcaseless() N/A
bisstemeqblk() N/A
bisstemeqcaselessblk() N/A
blength() cpr_string_size()
blengthe() cpr_string_size()
blk2bstr() N/A
bltrimws() N/A
bmidstr() N/A
bninchr() N/A
bninchrr() N/A
bpattern() N/A
breplace() N/A
brtrimws() N/A
bsetstr() N/A
bsplitcb() N/A
bsplitscb() N/A
bsplitstrcb() N/A
bstr2cstr() N/A
bstrchr() N/A
bstrchrp() N/A
bstrcmp() N/A
bstrcpy() N/A
bstricmp() N/A
bstrncmp() N/A
bstrnicmp() N/A
bstrrchr() N/A
bstrrchrp() N/A
btolower() N/A
btoupper() N/A
btrimws() N/A
btrunc() N/A
bvcformata() N/A
bvformata() N/A

See also

Better String Library
Documentation for the bstring library.