[ox/std] Make strops constexpr functions and use static_assert for tests
This commit is contained in:
parent
585d79a219
commit
8094e0fe4d
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8)
|
||||
add_library(
|
||||
OxStd
|
||||
assert.cpp
|
||||
byteswap.cpp
|
||||
memops.cpp
|
||||
random.cpp
|
||||
strops.cpp
|
||||
|
16
deps/ox/src/ox/std/assert.cpp
vendored
16
deps/ox/src/ox/std/assert.cpp
vendored
@ -6,16 +6,20 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#if defined(OX_USE_STDLIB)
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#endif
|
||||
#include <ox/__buildinfo/defines.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
void oxAssert(const char *file, int line, bool pass, const char *msg) {
|
||||
#if defined(OX_USE_STDLIB)
|
||||
void _assert(const char *file, int line, bool pass, const char *msg) {
|
||||
if (!pass) {
|
||||
std::cerr << '(' << file << ':' << line << "): " << msg << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void _assert(const char*, int, bool, const char*) {
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
10
deps/ox/src/ox/std/assert.hpp
vendored
10
deps/ox/src/ox/std/assert.hpp
vendored
@ -8,10 +8,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void oxAssert(const char *file, int line, bool pass, const char *msg);
|
||||
namespace ox {
|
||||
|
||||
void _assert(const char *file, int line, bool pass, const char *msg);
|
||||
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ox_assert(pass, msg) oxAssert(__FILE__, __LINE__, pass, msg)
|
||||
#define oxAssert(pass, msg) ox::_assert(__FILE__, __LINE__, pass, msg)
|
||||
#else
|
||||
#define ox_assert(pass, msg)
|
||||
#define oxAssert(pass, msg)
|
||||
#endif
|
||||
|
81
deps/ox/src/ox/std/byteswap.cpp
vendored
Normal file
81
deps/ox/src/ox/std/byteswap.cpp
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "byteswap.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool testBigEndianAdapt(T i) {
|
||||
return bigEndianAdapt(bigEndianAdapt(i)) == i;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool testLittleEndian(T i) {
|
||||
return LittleEndian<T>(i) == i;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool testBigEndian(T i) {
|
||||
return BigEndian<T>(i) == i;
|
||||
}
|
||||
|
||||
static_assert(testBigEndianAdapt<uint16_t>(0x00ff), "Test bigEndianAdapt 0x00ff");
|
||||
static_assert(testBigEndianAdapt<uint16_t>(0xff00), "Test bigEndianAdapt 0xff00");
|
||||
|
||||
static_assert(testBigEndianAdapt<uint32_t>(0x000000ff), "Test bigEndianAdapt 0x000000ff");
|
||||
static_assert(testBigEndianAdapt<uint32_t>(0x0000ff00), "Test bigEndianAdapt 0x0000ff00");
|
||||
static_assert(testBigEndianAdapt<uint32_t>(0x00ff0000), "Test bigEndianAdapt 0x00ff0000");
|
||||
static_assert(testBigEndianAdapt<uint32_t>(0xff000000), "Test bigEndianAdapt 0xff000000");
|
||||
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x00000000000000ff), "Test bigEndianAdapt 0x00000000000000ff");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x000000000000ff00), "Test bigEndianAdapt 0x000000000000ff00");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x0000000000ff0000), "Test bigEndianAdapt 0x0000000000ff0000");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x00000000ff000000), "Test bigEndianAdapt 0x00000000ff000000");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x000000ff00000000), "Test bigEndianAdapt 0x000000ff00000000");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x0000ff0000000000), "Test bigEndianAdapt 0x0000ff0000000000");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0x00ff000000000000), "Test bigEndianAdapt 0x00ff000000000000");
|
||||
static_assert(testBigEndianAdapt<uint64_t>(0xff00000000000000), "Test bigEndianAdapt 0xff00000000000000");
|
||||
|
||||
|
||||
static_assert(testLittleEndian<uint16_t>(0x00ff), "Test LittleEndian 0x00ff");
|
||||
static_assert(testLittleEndian<uint16_t>(0xff00), "Test LittleEndian 0xff00");
|
||||
|
||||
static_assert(testLittleEndian<uint32_t>(0x000000ff), "Test LittleEndian 0x000000ff");
|
||||
static_assert(testLittleEndian<uint32_t>(0x0000ff00), "Test LittleEndian 0x0000ff00");
|
||||
static_assert(testLittleEndian<uint32_t>(0x00ff0000), "Test LittleEndian 0x00ff0000");
|
||||
static_assert(testLittleEndian<uint32_t>(0xff000000), "Test LittleEndian 0xff000000");
|
||||
|
||||
static_assert(testLittleEndian<uint64_t>(0x00000000000000ff), "Test LittleEndian 0x00000000000000ff");
|
||||
static_assert(testLittleEndian<uint64_t>(0x000000000000ff00), "Test LittleEndian 0x000000000000ff00");
|
||||
static_assert(testLittleEndian<uint64_t>(0x0000000000ff0000), "Test LittleEndian 0x0000000000ff0000");
|
||||
static_assert(testLittleEndian<uint64_t>(0x00000000ff000000), "Test LittleEndian 0x00000000ff000000");
|
||||
static_assert(testLittleEndian<uint64_t>(0x000000ff00000000), "Test LittleEndian 0x000000ff00000000");
|
||||
static_assert(testLittleEndian<uint64_t>(0x0000ff0000000000), "Test LittleEndian 0x0000ff0000000000");
|
||||
static_assert(testLittleEndian<uint64_t>(0x00ff000000000000), "Test LittleEndian 0x00ff000000000000");
|
||||
static_assert(testLittleEndian<uint64_t>(0xff00000000000000), "Test LittleEndian 0xff00000000000000");
|
||||
|
||||
|
||||
static_assert(testBigEndian<uint16_t>(0x00ff), "Test BigEndian 0x00ff");
|
||||
static_assert(testBigEndian<uint16_t>(0xff00), "Test BigEndian 0xff00");
|
||||
|
||||
static_assert(testBigEndian<uint32_t>(0x000000ff), "Test BigEndian 0x000000ff");
|
||||
static_assert(testBigEndian<uint32_t>(0x0000ff00), "Test BigEndian 0x0000ff00");
|
||||
static_assert(testBigEndian<uint32_t>(0x00ff0000), "Test BigEndian 0x00ff0000");
|
||||
static_assert(testBigEndian<uint32_t>(0xff000000), "Test BigEndian 0xff000000");
|
||||
|
||||
static_assert(testBigEndian<uint64_t>(0x00000000000000ff), "Test BigEndian 0x00000000000000ff");
|
||||
static_assert(testBigEndian<uint64_t>(0x000000000000ff00), "Test BigEndian 0x000000000000ff00");
|
||||
static_assert(testBigEndian<uint64_t>(0x0000000000ff0000), "Test BigEndian 0x0000000000ff0000");
|
||||
static_assert(testBigEndian<uint64_t>(0x00000000ff000000), "Test BigEndian 0x00000000ff000000");
|
||||
static_assert(testBigEndian<uint64_t>(0x000000ff00000000), "Test BigEndian 0x000000ff00000000");
|
||||
static_assert(testBigEndian<uint64_t>(0x0000ff0000000000), "Test BigEndian 0x0000ff0000000000");
|
||||
static_assert(testBigEndian<uint64_t>(0x00ff000000000000), "Test BigEndian 0x00ff000000000000");
|
||||
static_assert(testBigEndian<uint64_t>(0xff00000000000000), "Test BigEndian 0xff00000000000000");
|
||||
|
||||
}
|
98
deps/ox/src/ox/std/byteswap.hpp
vendored
98
deps/ox/src/ox/std/byteswap.hpp
vendored
@ -11,51 +11,30 @@
|
||||
#include <ox/__buildinfo/defines.hpp>
|
||||
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
constexpr inline int8_t byteSwap(int8_t i) {
|
||||
template<typename T>
|
||||
constexpr inline T byteSwap(typename enable_if<sizeof(T) == 1, T>::type i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
constexpr inline int16_t byteSwap(int16_t i) {
|
||||
template<typename T>
|
||||
constexpr inline T byteSwap(typename enable_if<sizeof(T) == 2, T>::type i) {
|
||||
return (i << 8) | (i >> 8);
|
||||
}
|
||||
|
||||
constexpr inline int32_t byteSwap(int32_t i) {
|
||||
template<typename T>
|
||||
constexpr inline T byteSwap(typename enable_if<sizeof(T) == 4, T>::type i) {
|
||||
return ((i >> 24) & 0x000000ff) |
|
||||
((i >> 8) & 0x0000ff00) |
|
||||
((i << 8) & 0x00ff0000) |
|
||||
((i << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
constexpr inline int64_t byteSwap(int64_t i) {
|
||||
return ((i >> 56) & 0x00000000000000ff) |
|
||||
((i >> 40) & 0x000000000000ff00) |
|
||||
((i >> 24) & 0x0000000000ff0000) |
|
||||
((i >> 8) & 0x00000000ff000000) |
|
||||
((i << 8) & 0x000000ff00000000) |
|
||||
((i << 24) & 0x0000ff0000000000) |
|
||||
((i << 40) & 0x00ff000000000000) |
|
||||
((i << 56) & 0xff00000000000000);
|
||||
}
|
||||
|
||||
constexpr inline uint16_t byteSwap(uint8_t i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
constexpr inline uint16_t byteSwap(uint16_t i) {
|
||||
return (i << 8) | (i >> 8);
|
||||
}
|
||||
|
||||
constexpr inline uint32_t byteSwap(uint32_t i) {
|
||||
return ((i >> 24) & 0x000000ff) |
|
||||
((i >> 8) & 0x0000ff00) |
|
||||
((i << 8) & 0x00ff0000) |
|
||||
((i << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
constexpr inline uint64_t byteSwap(uint64_t i) {
|
||||
template<typename T>
|
||||
constexpr inline T byteSwap(typename enable_if<sizeof(T) == 8, T>::type i) {
|
||||
return ((i >> 56) & 0x00000000000000ff) |
|
||||
((i >> 40) & 0x000000000000ff00) |
|
||||
((i >> 24) & 0x0000000000ff0000) |
|
||||
@ -68,74 +47,81 @@ constexpr inline uint64_t byteSwap(uint64_t i) {
|
||||
|
||||
|
||||
/**
|
||||
* Takes an int and byte swaps if the platform is big endian.
|
||||
* Takes an int and byte swaps if the platform is the given condition is true.
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline T bigEndianAdapt(T i) {
|
||||
if constexpr(ox::defines::BigEndian) {
|
||||
return byteSwap(i);
|
||||
template<typename T, bool byteSwap>
|
||||
constexpr inline T conditionalByteSwap(T i) {
|
||||
if constexpr(byteSwap) {
|
||||
return ox::byteSwap<T>(i);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes an int and byte swaps if the platform is big endian.
|
||||
*/
|
||||
template<typename T>
|
||||
class __attribute__((packed)) LittleEndian {
|
||||
constexpr inline T bigEndianAdapt(T i) {
|
||||
return conditionalByteSwap<T, ox::defines::BigEndian>(i);
|
||||
}
|
||||
|
||||
|
||||
template<typename T, bool byteSwap>
|
||||
class __attribute__((packed)) ByteSwapInteger {
|
||||
private:
|
||||
T m_value;
|
||||
|
||||
public:
|
||||
constexpr inline LittleEndian() = default;
|
||||
constexpr inline ByteSwapInteger() = default;
|
||||
|
||||
constexpr inline LittleEndian(const LittleEndian &other) {
|
||||
constexpr inline ByteSwapInteger(const ByteSwapInteger &other) {
|
||||
m_value = other.m_value;
|
||||
}
|
||||
|
||||
constexpr inline LittleEndian(T value) {
|
||||
m_value = ox::bigEndianAdapt(value);
|
||||
constexpr inline ByteSwapInteger(T value): m_value(ox::conditionalByteSwap<T, byteSwap>(value)) {
|
||||
}
|
||||
|
||||
constexpr inline const LittleEndian &operator=(const LittleEndian &other) {
|
||||
constexpr inline const ByteSwapInteger &operator=(const ByteSwapInteger &other) {
|
||||
m_value = other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator=(I value) {
|
||||
m_value = ox::bigEndianAdapt(value);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
constexpr inline operator T() const {
|
||||
return ox::bigEndianAdapt(m_value);
|
||||
return ox::conditionalByteSwap<T, byteSwap>(m_value);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator+=(I other) {
|
||||
auto newVal = *this + other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator-=(I other) {
|
||||
auto newVal = *this - other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator*=(I other) {
|
||||
auto newVal = *this * other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator/=(I other) {
|
||||
auto newVal = *this / other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@ -166,38 +152,44 @@ class __attribute__((packed)) LittleEndian {
|
||||
template<typename I>
|
||||
constexpr inline T operator&=(I other) {
|
||||
auto newVal = *this & other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator|=(I other) {
|
||||
auto newVal = *this | other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator^=(I other) {
|
||||
auto newVal = *this ^ other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator>>=(I other) {
|
||||
auto newVal = *this >> other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr inline T operator<<=(I other) {
|
||||
auto newVal = *this << other;
|
||||
m_value = ox::bigEndianAdapt(newVal);
|
||||
m_value = ox::conditionalByteSwap<T, byteSwap>(newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using LittleEndian = ByteSwapInteger<T, ox::defines::BigEndian>;
|
||||
|
||||
template<typename T>
|
||||
using BigEndian = ByteSwapInteger<T, !ox::defines::BigEndian>;
|
||||
|
||||
}
|
||||
|
8
deps/ox/src/ox/std/memops.cpp
vendored
8
deps/ox/src/ox/std/memops.cpp
vendored
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||
*
|
||||
@ -5,12 +6,13 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#include "memops.hpp"
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
int ox_memcmp(const void *ptr1, const void *ptr2, size_t size) {
|
||||
int retval = 0;
|
||||
auto block1 = ((uint8_t*) ptr1);
|
||||
auto block2 = ((uint8_t*) ptr2);
|
||||
auto block1 = reinterpret_cast<const uint8_t*>(ptr1);
|
||||
auto block2 = reinterpret_cast<const uint8_t*>(ptr2);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (block1[i] < block2[i]) {
|
||||
retval = -1;
|
||||
|
120
deps/ox/src/ox/std/strops.cpp
vendored
120
deps/ox/src/ox/std/strops.cpp
vendored
@ -6,110 +6,24 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "math.hpp"
|
||||
|
||||
#include "strops.hpp"
|
||||
|
||||
int ox_strcmp(const char *str1, const char *str2) {
|
||||
auto retval = 0;
|
||||
auto i = 0;
|
||||
while (str1[i] || str2[i]) {
|
||||
if (str1[i] < str2[i]) {
|
||||
retval = -1;
|
||||
break;
|
||||
} else if (str1[i] > str2[i]) {
|
||||
retval = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
static_assert(ox_strcmp("asdf", "hijk") < 0, "asdf < hijk");
|
||||
static_assert(ox_strcmp("hijk", "asdf") > 0, "hijk > asdf");
|
||||
static_assert(ox_strcmp("resize", "read") > 0, "resize > read");
|
||||
static_assert(ox_strcmp("read", "resize") < 0, "read < resize");
|
||||
static_assert(ox_strcmp("resize", "resize") == 0, "resize == resize");
|
||||
static_assert(ox_strcmp("", "") == 0, "\"\" == \"\"");
|
||||
|
||||
const char *ox_strchr(const char *str, int character, size_t maxLen) {
|
||||
for (size_t i = 0; i <= maxLen; i++) {
|
||||
if (str[i] == character) {
|
||||
return &str[i];
|
||||
} else if (str[i] == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static_assert([] {
|
||||
auto testStr = "asdf";
|
||||
return ox_strchr(testStr, 0, 4) == &testStr[4];
|
||||
}(), "ox_strchr 0");
|
||||
|
||||
char *ox_strchr(char *str, int character, size_t maxLen) {
|
||||
for (size_t i = 0; i < maxLen; i++) {
|
||||
if (str[i] == character) {
|
||||
return &str[i];
|
||||
} else if (str[i] == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ox_lastIndexOf(const char *str, int character, int maxLen) {
|
||||
int retval = -1;
|
||||
for (int i = 0; i < maxLen && str[i]; i++) {
|
||||
if (str[i] == character) {
|
||||
retval = i;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ox_lastIndexOf(char *str, int character, int maxLen) {
|
||||
int retval = -1;
|
||||
for (int i = 0; i < maxLen && str[i]; i++) {
|
||||
if (str[i] == character) {
|
||||
retval = i;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ox_atoi(const char *str) {
|
||||
int total = 0;
|
||||
int multiplier = 1;
|
||||
|
||||
for (auto i = ox_strlen(str) - 1; i != -1; i--) {
|
||||
total += (str[i] - '0') * multiplier;
|
||||
multiplier *= 10;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
char *ox_itoa(int64_t v, char *str) {
|
||||
if (v) {
|
||||
auto mod = 1000000000000000000;
|
||||
constexpr auto base = 10;
|
||||
auto it = 0;
|
||||
if (v < 0) {
|
||||
str[it] = '-';
|
||||
it++;
|
||||
}
|
||||
while (mod) {
|
||||
auto digit = v / mod;
|
||||
v %= mod;
|
||||
mod /= base;
|
||||
if (it or digit) {
|
||||
int start;
|
||||
if (digit < 10) {
|
||||
start = '0';
|
||||
} else {
|
||||
start = 'a';
|
||||
digit -= 10;
|
||||
}
|
||||
str[it] = start + digit;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
str[it] = 0;
|
||||
} else {
|
||||
// 0 is a special case
|
||||
str[0] = '0';
|
||||
str[1] = 0;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
static_assert([] {
|
||||
int retval = 0;
|
||||
auto testStr = "aaaa";
|
||||
retval |= !(ox_lastIndexOf((char*) testStr, 'a', ox_strlen(testStr)) == 3);
|
||||
retval |= !(ox_lastIndexOf((const char*) testStr, 'a', ox_strlen(testStr)) == 3);
|
||||
return retval == 0;
|
||||
}(), "ox_lastIndexOf aaaa a");
|
||||
|
105
deps/ox/src/ox/std/strops.hpp
vendored
105
deps/ox/src/ox/std/strops.hpp
vendored
@ -8,11 +8,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "math.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
int ox_strcmp(const char *str1, const char *str2);
|
||||
|
||||
constexpr int ox_strlen(const char *str1) {
|
||||
int len = 0;
|
||||
for (; str1[len]; len++);
|
||||
@ -25,14 +24,104 @@ constexpr int ox_strlen(char *str1) {
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *ox_strchr(const char *str, int character, size_t maxLen = 0xFFFFFFFF);
|
||||
constexpr int ox_strcmp(const char *str1, const char *str2) {
|
||||
auto retval = 0;
|
||||
auto i = 0;
|
||||
while (str1[i] || str2[i]) {
|
||||
if (str1[i] < str2[i]) {
|
||||
retval = -1;
|
||||
break;
|
||||
} else if (str1[i] > str2[i]) {
|
||||
retval = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *ox_strchr(char *str, int character, size_t maxLen = 0xFFFFFFFF);
|
||||
constexpr const char *ox_strchr(const char *str, int character, size_t maxLen = 0xFFFFFFFF) {
|
||||
for (size_t i = 0; i <= maxLen; i++) {
|
||||
if (str[i] == character) {
|
||||
return &str[i];
|
||||
} else if (str[i] == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ox_lastIndexOf(const char *str, int character, int maxLen = 0xFFFFFFFF);
|
||||
constexpr char *ox_strchr(char *str, int character, size_t maxLen = 0xFFFFFFFF) {
|
||||
for (size_t i = 0; i < maxLen; i++) {
|
||||
if (str[i] == character) {
|
||||
return &str[i];
|
||||
} else if (str[i] == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ox_lastIndexOf(char *str, int character, int maxLen = 0xFFFFFFFF);
|
||||
constexpr int ox_lastIndexOf(const char *str, int character, int maxLen = 0xFFFFFFFF) {
|
||||
int retval = -1;
|
||||
for (int i = 0; i < maxLen && str[i]; i++) {
|
||||
if (str[i] == character) {
|
||||
retval = i;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ox_atoi(const char *str);
|
||||
constexpr int ox_lastIndexOf(char *str, int character, int maxLen = 0xFFFFFFFF) {
|
||||
int retval = -1;
|
||||
for (int i = 0; i < maxLen && str[i]; i++) {
|
||||
if (str[i] == character) {
|
||||
retval = i;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *ox_itoa(int64_t v, char *str);
|
||||
constexpr int ox_atoi(const char *str) {
|
||||
int total = 0;
|
||||
int multiplier = 1;
|
||||
|
||||
for (auto i = ox_strlen(str) - 1; i != -1; i--) {
|
||||
total += (str[i] - '0') * multiplier;
|
||||
multiplier *= 10;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
constexpr char *ox_itoa(int64_t v, char *str) {
|
||||
if (v) {
|
||||
auto mod = 1000000000000000000;
|
||||
constexpr auto base = 10;
|
||||
auto it = 0;
|
||||
if (v < 0) {
|
||||
str[it] = '-';
|
||||
it++;
|
||||
}
|
||||
while (mod) {
|
||||
auto digit = v / mod;
|
||||
v %= mod;
|
||||
mod /= base;
|
||||
if (it or digit) {
|
||||
int start = '0';
|
||||
if (digit >= 10) {
|
||||
start = 'a';
|
||||
digit -= 10;
|
||||
}
|
||||
str[it] = start + digit;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
str[it] = 0;
|
||||
} else {
|
||||
// 0 is a special case
|
||||
str[0] = '0';
|
||||
str[1] = 0;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
56
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
56
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
@ -11,59 +11,3 @@ add_test("Test\\ ox_memcmp\\ ABCDEFG\\ !=\\ HIJKLMN" StdTest "ABCDEFG != HIJKLMN
|
||||
add_test("Test\\ ox_memcmp\\ HIJKLMN\\ !=\\ ABCDEFG" StdTest "HIJKLMN != ABCDEFG")
|
||||
add_test("Test\\ ox_memcmp\\ ABCDEFG\\ ==\\ ABCDEFG" StdTest "ABCDEFG == ABCDEFG")
|
||||
add_test("Test\\ ox_memcmp\\ ABCDEFGHI\\ ==\\ ABCDEFG" StdTest "ABCDEFGHI == ABCDEFG")
|
||||
|
||||
|
||||
################################################################################
|
||||
# StrOps Tests
|
||||
|
||||
add_executable(
|
||||
StrOpsTest
|
||||
strops_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
StrOpsTest
|
||||
OxStd
|
||||
OxTrace
|
||||
)
|
||||
|
||||
add_test("Test\\ ox_strcmp\\ asdf\\ !=\\ hijk" StrOpsTest "asdf < hijk")
|
||||
add_test("Test\\ ox_strcmp\\ hijk\\ !=\\ asdf" StrOpsTest "hijk > asdf")
|
||||
add_test("Test\\ ox_strcmp\\ read\\ !=\\ resize" StrOpsTest "read < resize")
|
||||
add_test("Test\\ ox_strcmp\\ resize\\ !=\\ read" StrOpsTest "resize > read")
|
||||
add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest "resize == resize")
|
||||
add_test("Test\\ ox_strcmp\\ ''\\ ==\\ ''" StrOpsTest " == ")
|
||||
add_test("Test\\ ox_strchr\\ 0" StrOpsTest "ox_strchr 0")
|
||||
add_test("Test\\ ox_lastIndexOf\\ aaaa\\ a" StrOpsTest "ox_lastIndexOf aaaa a")
|
||||
|
||||
|
||||
################################################################################
|
||||
# Byte Swap Tests
|
||||
|
||||
add_executable(
|
||||
ByteSwapTest
|
||||
byteswap_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
ByteSwapTest
|
||||
OxStd
|
||||
OxTrace
|
||||
)
|
||||
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x00ff" ByteSwapTest bigEndianAdapt<uint16_t> 0x00ff)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0xff00" ByteSwapTest bigEndianAdapt<uint16_t> 0xff00)
|
||||
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x000000ff" ByteSwapTest bigEndianAdapt<uint32_t> 0x000000ff)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x0000ff00" ByteSwapTest bigEndianAdapt<uint32_t> 0x0000ff00)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x00ff0000" ByteSwapTest bigEndianAdapt<uint32_t> 0x00ff0000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0xff000000" ByteSwapTest bigEndianAdapt<uint32_t> 0xff000000)
|
||||
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x00000000000000ff" ByteSwapTest bigEndianAdapt<uint64_t> 0x00000000000000ff)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x000000000000ff00" ByteSwapTest bigEndianAdapt<uint64_t> 0x000000000000ff00)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x0000000000ff0000" ByteSwapTest bigEndianAdapt<uint64_t> 0x0000000000ff0000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x00000000ff000000" ByteSwapTest bigEndianAdapt<uint64_t> 0x00000000ff000000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x000000ff00000000" ByteSwapTest bigEndianAdapt<uint64_t> 0x000000ff00000000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x0000ff0000000000" ByteSwapTest bigEndianAdapt<uint64_t> 0x0000ff0000000000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0x00ff000000000000" ByteSwapTest bigEndianAdapt<uint64_t> 0x00ff000000000000)
|
||||
add_test("Test\\ bigEndianAdapt\\ 0xff00000000000000" ByteSwapTest bigEndianAdapt<uint64_t> 0xff00000000000000)
|
||||
|
39
deps/ox/src/ox/std/test/byteswap_test.cpp
vendored
39
deps/ox/src/ox/std/test/byteswap_test.cpp
vendored
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ox;
|
||||
|
||||
template<typename T>
|
||||
int testBigEndianAdapt(string str) {
|
||||
auto i = (T) stoull(str, nullptr, 16);
|
||||
return !(bigEndianAdapt(bigEndianAdapt(i)) == i);
|
||||
}
|
||||
|
||||
map<string, int(*)(string)> tests = {
|
||||
{
|
||||
{ "bigEndianAdapt<uint16_t>", testBigEndianAdapt<uint16_t> },
|
||||
{ "bigEndianAdapt<uint32_t>", testBigEndianAdapt<uint32_t> },
|
||||
{ "bigEndianAdapt<uint64_t>", testBigEndianAdapt<uint64_t> },
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int retval = -1;
|
||||
if (argc > 1) {
|
||||
auto testName = args[1];
|
||||
string testArg = args[2];
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = tests[testName](testArg);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
79
deps/ox/src/ox/std/test/strops_test.cpp
vendored
79
deps/ox/src/ox/std/test/strops_test.cpp
vendored
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
map<string, function<int()>> tests = {
|
||||
{
|
||||
"asdf < hijk",
|
||||
[]() {
|
||||
return !(ox_strcmp("asdf", "hijk") < 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"hijk > asdf",
|
||||
[]() {
|
||||
return !(ox_strcmp("hijk", "asdf") > 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"resize > read",
|
||||
[]() {
|
||||
return !(ox_strcmp("resize", "read") > 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"read < resize",
|
||||
[]() {
|
||||
return !(ox_strcmp("read", "resize") < 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"resize == resize",
|
||||
[]() {
|
||||
return !(ox_strcmp("resize", "resize") == 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
" == ",
|
||||
[]() {
|
||||
return !(ox_strcmp("", "") == 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"ox_strchr 0",
|
||||
[]() {
|
||||
auto testStr = "asdf";
|
||||
return !(ox_strchr(testStr, 0, 4) == &testStr[4]);
|
||||
}
|
||||
},
|
||||
{
|
||||
"ox_lastIndexOf aaaa a",
|
||||
[]() {
|
||||
int retval = 0;
|
||||
auto testStr = "aaaa";
|
||||
retval |= !(ox_lastIndexOf((char*) testStr, 'a', ox_strlen(testStr)) == 3);
|
||||
retval |= !(ox_lastIndexOf((const char*) testStr, 'a', ox_strlen(testStr)) == 3);
|
||||
return retval;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
if (argc > 1) {
|
||||
auto testName = args[1];
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
return tests[testName]();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
24
deps/ox/src/ox/std/types.hpp
vendored
24
deps/ox/src/ox/std/types.hpp
vendored
@ -29,7 +29,29 @@ typedef uint64_t uintmax_t;
|
||||
|
||||
namespace ox {
|
||||
|
||||
typedef uint32_t Error;
|
||||
using Error = uint32_t;
|
||||
|
||||
template<typename T>
|
||||
struct ValErr {
|
||||
T value;
|
||||
Error error;
|
||||
|
||||
inline constexpr ValErr() = default;
|
||||
|
||||
inline constexpr ValErr(T value, Error error = 0) {
|
||||
this->value = value;
|
||||
this->error = error;
|
||||
}
|
||||
|
||||
inline constexpr operator T&() {
|
||||
return value;
|
||||
}
|
||||
|
||||
inline constexpr bool ok() {
|
||||
return error == 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user