Skip to content
@q-tee

q-tee

collection of tiny, lightweight and cross-platform libraries for various tasks

⚡ about

q-tee is a collection of tiny, lightweight and cross-platform (if not stated otherwise) libraries for various tasks. the main goal of this collection is to maximize the reuse of its components with each other, in order to reduce the size, ease of maintenance and classification of individual libraries. to reduce redundant duplication per each repository below goes common information you may need.

🛠️ getting started

Warning

libraries present there require root folder of the collection to be named q-tee and listed in your project's include directories.
e.g. project/dependencies/q-tee/<LIBRARY_NAME>

  • installation using Git Submodules: run the following command in the Git Bash to install particular library into your project:
git submodule add https://github.com/q-tee/<LIBRARY_NAME> [OPTIONAL_PATH]
git submodule update --init

to checkout submodules to the remote tracking branch, run the following command in the Git Bash:

git submodule update --recursive --remote [OPTIONAL_NAME]
  • manual installation: run the following command in the Git Bash to download particular library into your project:
git clone https://github.com/q-tee/<LIBRARY_NAME> [OPTIONAL_PATH]

Note

the preferred way to install each library is using Git Submodules. list of the dependent submodules within this collection required by a particular library and further specific information is given in its README file.

⭐ contribution

if you encounter any unexpected behaviour, have question or suggestion, please open an issue and provide a detailed explanation. want to speed up the progress or add a new feature? feel free to make a pull request, please don't forget to follow the project code style.

📄 code style

Note

conditions are sorted by their priority, if a higher priority condition overrides condition with a lower priority, then it is preferred. we're prefer concrete and explicit definitions and naming over simplicity, but remain readability.

general

break

  1. line breaks must be LF (line feed, single '\n' character without carriage return '\r' character).
  2. braces with short aggregate initialization, short lambda expression can be on same line.
std::array<std::pair<int, float>> arrName{{ { 0, 0.0f } }};
bool fnName = [&x](const auto& name) { return name.x > x; };
  1. each brace must be on it's own line, except when enclosed body are empty.
void Function()
{
	int iName = 0;
}

void EmptyFunction() { };
  1. one-line body statements, must be on new-line.
if (bCondition)
	Function();

while (bCondition)
	Function();

for (int i = 0; i < n; i++)
	Function(i);

space

  1. must be placed after pointer/reference to align them on left side, except declarations of multiple variables.
void* pName = nullptr;
char *szNameFirst = nullptr, *szNameSecond = nullptr;
std::string& strName = "name";
std::string&& strName = "name";
  1. must be placed around assignment/ternary/binary but not unary/member operators.
iName = -iName;
uName = (uName & 0x2);
bName = (bName ? true : false);
  1. must be placed after keyword in the flow control statements.
while (bName)
{
	if (bName)
		bName = !bName;
}
  1. must be placed between empty curve/square braces, such as list initialization, constructor with initializer list, lambda capture etc, but not aggregate initialization.
int iName = { };
std::array<std::pair<int, float>> arrName{{ { 0, 0.0f } }};

Name_t(const int iName) :
	iName(iName) { }

auto fnName = [ ](int& nNameCount) { nNameCount++; };
  1. must be placed after comma and colon, except conditions when new line must be placed instead.
int iName = 0, iSecondName = 0;

class CDerived : IBase { };

Name_t(const int iName) :
	iName(iName) { }

comment

  • hot words:

    1. @todo: <explanation> - explains things to do/fix/improve in the future.

    2. @note: <info> - recommended information for the user to read.

    3. @test: [date] <reason> - explains things to test for the some reason.

    4. @credits: <author> - credentials of the author of the used/referenced code.

  1. preferred to be in lowercase, except when the extra attention is required.
  2. stylistic comments must be written in doxygen style, with spaces around colon.
  3. multi-line comments less than 5 lines must be written in C++ style (double-slash and triple-slash for stylistic), otherwise C style must be used (slash with asterisk and slash with double-asterisk for stylistic).

macro

  1. the name must be written in UPPER_SNAKE_CASE.
#define Q_NAME
  1. arguments must be written in UPPER_SNAKE_CASE.
#define Q_STRINGIFY(PLAIN_NAME) #PLAIN_NAME
  1. arguments must be enclosed in parenthesis if they can be used as an expression.
#define Q_NAME(X) ((X) / 3.0f)
float flName = Q_NAME(5.0f - 8.0f);
  1. expression must be enclosed in parenthesis.
#define Q_NAME (-1)
  1. if the macro is publicly exposed, then it must be prefixed with 'Q' to indicate that its part of the q-tee collection.
#define Q_NAME
  1. if the macro should be used only internally, then it must be prefixed with '_'.
#define _Q_INTERNAL

flow control

  1. when comparing an unknown value with a constant/keyword value, first must be on the left side of comparison.
if (flName < 0.0f || flName > M_PI)
  1. check for pointer validity shouldn't look like a boolean check and must be compared explicitly with keyword.
if (pName != nullptr)
  1. check for result of expression when it may not be in range [0, 1] shouldn't look like a boolean check and must be compared explicitly.
if ((uName & 0xAF) != 0U)

literals

  • number literals:

    1. differentiate numbers use with lowercase hex/binary/exponent/binary-exponent literals.

     unsigned int uNameAddress = 0x1EE7;
     unsigned int uNameBits = 0b1100100;
     float flNamePower = 0x1p4f;

    2. specify number data type with UPPERCASE (except float, with lowercase) type literal.

     unsigned int uName = 0U;
     long lName = 0L;
     long long llName = 0LL;
     long double ldName = 0.0L;
     float flName = 0.0f;

    3. wrap long constant numbers with apostrophe literal.

     int iName = 2'147'483'648;
  • string literals

    1. wrap string that frequently contain code escapes with UPPERCASE raw string literal.

     std::string strName = R"(no new \n line)";

    2. specify string/character encoding with case-sensetive literal.

     wchar_t wName = L'\u2764';
     std::wstring wstrName = L"\u2764"s;
     char8_t uchName = u8'\u00AE';
     std::u8string ustrName = u8"\u2764"s;
     char16_t uchName = u'\u2764';
     std::u16string ustrName = u"\u2764"s;
     char32_t uchName = U'\U0010FFFF';
     std::u32string ustrName = U"\U0010FFFF"s;

    3. specify string type with custom literal.

     std::string strName = "string"s;
     std::string_view strName = "string"sv;
naming conventions

function

  1. function name must be written in PascalCase.
void FunctionName();

variable

  1. variable name must be written in camelCase and prefixed with Hungarian notation of the data type that listed below or based on STL/WinAPI.
    • pointer:

      1. if the variable supposed to be a handle of any data type, prefix with 'h' overriding any other prefix.

       HANDLE hName = nullptr;

      2. if the variable is a function argument and supposed to be used as output, prefix with 'p' and append the variable's data type if specified.

       void Function(unsigned int* puOutput);

      3. if none of the conditions are met, prefix with 'p' overriding any other data type prefix.

       std::uint32_t* pName = &uAddress;
    • function:

      1. no additional conditions.

       void (*fnName)() = nullptr;
    • container:

      1. fixed-size C/C++/STL massive variable must be prefixed with 'arr'.

       char arrName[20] = { };
       std::array<char, 20U> arrName = { };

      2. varying-size C/C++/STL container variable must be prefixed with 'vec'.

       int* vecName = malloc(nSize);
       int* vecName = new int[nSize];
       std::vector<int> vecName = { };
    • boolean:

      1. no additional conditions.

       bool bName = false;
    • integer:

      1. if the variable is unsigned, prefix becomes 'u' regardless the data type, except long qualifiers, where it must be prepended instead.

       std::uint8_t uNameByte = 0U;
       std::uint16_t uNameWord = 0U;
       std::uint32_t uNameDword = 0U;
       std::uint64_t ullNameQword = 0ULL;

      2. if the variable supposed to indicate index/count/size/enumerator, prefix becomes 'n' regardless the data type.

       std::ptrdiff_t nNameIndex = arrName.find(...);
       std::size_t nNameSize = arrName.size();
       std::ptrdiff_t nNameCount = arrName.size() - arrInvalidName.size();
       ENameMode nNameMode = NAME_MODE_FIRST;

      3. if none of the conditions are met.

       char chName;
       short shName;
       int iName;
       long long llName;
    • floating point:

      1. no additional conditions.

       float flName = 0.0f;
       double dlName = 0.0;
       long double ldName = 0.0L;
    • string:

      1. if the variable a zero-terminated string it must be prefixed with 'sz' and safe wrapped string variables with 'str'.

       const char* szName = "";
       std::string strName = ""s;

      2. if the variable a string of the next base character types: wchar_t, char8_t, char16_t, char32_t it must prepend characters's data type to the prefix.

       const wchar_t* wszName = L"Example";
       const char8_t* uszName = u8"Example";
       const char16_t* uszName = u"Example";
       const char32_t* uszName = U"Example";
       std::wstring wstrName = L"Example"s;
       std::u8string ustrName = u8"Example"s;
       std::u16string ustrName = u"Example"s;
       std::u32string ustrName = U"Example"s;

      3. if the variable a string with template-based character type, it must prepend 't' to the prefix.

       template <typename T>
       void FunctionName(const T* tszName, const std::basic_string_view<T> tstrName);

      4. if the variable is a single character.

       char chName = '\0';
       wchar_t wchName = L'\000';
       char8_t uchName = u8'\u0000';
       char16_t uchName = u'\u0000';
       char32_t uchName = U'\U00000000';
    • other:

      1. if the data type of the variable is part of the STL.

       std::filesystem::path pathName = { };
       std::ifstream ifsName = { };
       std::ofstream ofsName = { };

      2. if the data type of the variable is part of the WinAPI.

       DWORD dwName = 0UL;
       WORD wName = 0U;
       BYTE dName = 0U;
       WPARAM wName = 0U;
       LPARAM lName = 0L;
       HRESULT hName = 0L;
       LRESULT lName = 0L;
  2. if variable defined as auto type, and final type is known, it still requires to include Hungarian notation.
auto iName = 0;
  1. if variable is a numeric constant known at compile-time, then it must be prefixed with 'k'.
constexpr int kPiDigitsCount = 6;
constexpr double kPi = 3.141592;
  1. if none of the conditions are met, then Hungarian notation is redundant.
Unknown_t unknownName = { };

structure

  1. must be suffixed with '_t' to indicate that it's a structure.
struct Name_t;

class

  1. if the class is either abstract or interface (has a virtual table and no variables), then it must be prefixed with 'I'.
class IName;
  1. must be prefixed with 'C' to indicate that it's a class.
class CName;

enumeration

  1. must be prefixed with 'E' to indicate that it's an enumeration.
enum EName : int { };
  1. the name of the each enumerator must be written in UPPER_SNAKE_CASE.
enum EName : int
{
	NAME_FIRST = 0,
	NAME_SECOND
};

namespace

  1. it is preferred the name to be written in UPPER_SNAKE_CASE.
namespace F;
  1. it is preferred to give a namespace short and generalized name.
namespace NT;
  1. if the child namespace is part of a particular module, then it must be named or prefixed by at least one letter of the module name

gui/font.h

namespace GUI::F;

Popular repositories Loading

  1. .github .github Public

  2. common common Public

    common, frequently used definitions and user overrides shared across the q-tee library collection

    C++

  3. crt crt Public

    a lightweight and efficient implementation of the C-runtime standard library for C++20

    C++

  4. tools tools Public

    implementation of the tools used for generation or manipulation of data used by the q-tee library collection

    C++

  5. hash hash Public

    collection of lightweight implementations of the non-cryptographic hash algorithms for C++20, with compile-time variants for each

    C++

  6. test test Public

    unit tests of methods provided by the q-tee library to ensure their correctness

    C++

Repositories

Showing 8 of 8 repositories

People

This organization has no public members. You must be a member to see who’s a part of this organization.

Top languages

Loading…

Most used topics

Loading…