From c812c92d1a1835f0bda783e709481188c8d92225 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 15 Mar 2014 19:34:59 -0700 Subject: Clean up header organization --- src/compat/alg.cpp | 3 ++ src/compat/alg.hpp | 21 +++++++++++ src/compat/attr.hpp | 13 +++++++ src/compat/cast.cpp | 3 ++ src/compat/cast.hpp | 54 +++++++++++++++++++++++++++ src/compat/fun.hpp | 11 ++++++ src/compat/iter.cpp | 3 ++ src/compat/iter.hpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ src/compat/iter_test.cpp | 82 ++++++++++++++++++++++++++++++++++++++++ src/compat/memory.cpp | 3 ++ src/compat/memory.hpp | 27 ++++++++++++++ src/compat/nullpo.cpp | 28 ++++++++++++++ src/compat/nullpo.hpp | 41 ++++++++++++++++++++ src/compat/rawmem.cpp | 3 ++ src/compat/rawmem.hpp | 30 +++++++++++++++ 15 files changed, 419 insertions(+) create mode 100644 src/compat/alg.cpp create mode 100644 src/compat/alg.hpp create mode 100644 src/compat/attr.hpp create mode 100644 src/compat/cast.cpp create mode 100644 src/compat/cast.hpp create mode 100644 src/compat/fun.hpp create mode 100644 src/compat/iter.cpp create mode 100644 src/compat/iter.hpp create mode 100644 src/compat/iter_test.cpp create mode 100644 src/compat/memory.cpp create mode 100644 src/compat/memory.hpp create mode 100644 src/compat/nullpo.cpp create mode 100644 src/compat/nullpo.hpp create mode 100644 src/compat/rawmem.cpp create mode 100644 src/compat/rawmem.hpp (limited to 'src/compat') diff --git a/src/compat/alg.cpp b/src/compat/alg.cpp new file mode 100644 index 0000000..7800e79 --- /dev/null +++ b/src/compat/alg.cpp @@ -0,0 +1,3 @@ +#include "alg.hpp" + +#include "../poison.hpp" diff --git a/src/compat/alg.hpp b/src/compat/alg.hpp new file mode 100644 index 0000000..250c161 --- /dev/null +++ b/src/compat/alg.hpp @@ -0,0 +1,21 @@ +#ifndef TMWA_COMPAT_ALG_HPP +#define TMWA_COMPAT_ALG_HPP + +# include "../sanity.hpp" + +# include + + +template +typename std::common_type::type min(A a, B b) +{ + return a < b ? a : b; +} + +template +typename std::common_type::type max(A a, B b) +{ + return b < a ? a : b; +} + +#endif // TMWA_COMPAT_ALG_HPP diff --git a/src/compat/attr.hpp b/src/compat/attr.hpp new file mode 100644 index 0000000..ca9a7a2 --- /dev/null +++ b/src/compat/attr.hpp @@ -0,0 +1,13 @@ +#ifndef TMWA_COMPAT_ATTR_HPP +#define TMWA_COMPAT_ATTR_HPP + +# include "../sanity.hpp" + + +# ifdef __clang__ +# define FALLTHROUGH [[clang::fallthrough]] +# else +# define FALLTHROUGH /* fallthrough */ +# endif + +#endif // TMWA_COMPAT_ATTR_HPP diff --git a/src/compat/cast.cpp b/src/compat/cast.cpp new file mode 100644 index 0000000..015fd27 --- /dev/null +++ b/src/compat/cast.cpp @@ -0,0 +1,3 @@ +#include "cast.hpp" + +#include "../poison.hpp" diff --git a/src/compat/cast.hpp b/src/compat/cast.hpp new file mode 100644 index 0000000..c1b9bab --- /dev/null +++ b/src/compat/cast.hpp @@ -0,0 +1,54 @@ +#ifndef TMWA_COMPAT_CAST_HPP +#define TMWA_COMPAT_CAST_HPP + +# include "../sanity.hpp" + +# include +# include + + +template +const T& const_(T& t) +{ + return t; +} + +template +T no_cast(U&& u) +{ + typedef typename std::remove_reference::type Ti; + typedef typename std::remove_reference::type Ui; + typedef typename std::remove_cv::type Tb; + typedef typename std::remove_cv::type Ub; + static_assert(std::is_same::value, "not no cast"); + return std::forward(u); +} + +template +T base_cast(U&& u) +{ + static_assert(std::is_reference::value, "must base cast with references"); + typedef typename std::remove_reference::type Ti; + typedef typename std::remove_reference::type Ui; + typedef typename std::remove_cv::type Tb; + typedef typename std::remove_cv::type Ub; + static_assert(std::is_base_of::value, "not base cast"); + return std::forward(u); +} + +// use this when e.g. U is an int of unknown size +template +T maybe_cast(U u) +{ + return u; +} + +template +typename std::remove_pointer::type *sign_cast(U *u) +{ + typedef typename std::remove_pointer::type T_; + static_assert(sizeof(T_) == sizeof(U), "sign cast must be same size"); + return reinterpret_cast(u); +} + +#endif // TMWA_COMPAT_CAST_HPP diff --git a/src/compat/fun.hpp b/src/compat/fun.hpp new file mode 100644 index 0000000..536a113 --- /dev/null +++ b/src/compat/fun.hpp @@ -0,0 +1,11 @@ +#ifndef TMWA_COMPAT_FUN_HPP +#define TMWA_COMPAT_FUN_HPP + +# include "../sanity.hpp" + +# include + + +namespace ph = std::placeholders; + +#endif // TMWA_COMPAT_FUN_HPP diff --git a/src/compat/iter.cpp b/src/compat/iter.cpp new file mode 100644 index 0000000..2b1fb0c --- /dev/null +++ b/src/compat/iter.cpp @@ -0,0 +1,3 @@ +#include "iter.hpp" + +#include "../poison.hpp" diff --git a/src/compat/iter.hpp b/src/compat/iter.hpp new file mode 100644 index 0000000..7793d90 --- /dev/null +++ b/src/compat/iter.hpp @@ -0,0 +1,97 @@ +#ifndef TMWA_COMPAT_ITER_HPP +#define TMWA_COMPAT_ITER_HPP +// iter.hpp - tools for dealing with iterators +// +// Copyright © 2012-2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +# include "../sanity.hpp" + +# include + + +/// Simple class to use a pair of iterators with foreach +template +class IteratorPair +{ + It _b, _e; +public: + IteratorPair(It b, It e) + : _b(b), _e(e) + {} + + It begin() { return _b; } + It end() { return _e; } +}; + +template +IteratorPair iterator_pair(It b, It e) +{ + return {b, e}; +} + +template +class PassthroughMath +{ +public: + static + T inced(T v) { return ++v; } +}; + +// An iterator that just directly contains an integer-like value +// TODO port this once the new integer API happens +template> +class ValueIterator +{ + T value; +public: + typedef std::forward_iterator_tag iterator_category; + typedef void difference_type; + typedef T value_type; + typedef void reference; + typedef void pointer; +public: + ValueIterator(T v) + : value(v) + {} + + T operator *() + { + return value; + } + ValueIterator& operator++ () + { + value = Math::inced(value); + return *this; + } + friend bool operator == (ValueIterator l, ValueIterator r) + { + return l.value == r.value; + } + friend bool operator != (ValueIterator l, ValueIterator r) + { + return !(l == r); + } +}; + +template +IteratorPair> value_range(T b, T e) +{ + return {b, e}; +} + +#endif // TMWA_COMPAT_ITER_HPP diff --git a/src/compat/iter_test.cpp b/src/compat/iter_test.cpp new file mode 100644 index 0000000..647ebf9 --- /dev/null +++ b/src/compat/iter_test.cpp @@ -0,0 +1,82 @@ +#include "iter.hpp" + +#include + +#include "../strings/xstring.hpp" + +TEST(iterpair, string) +{ + IteratorPair> pair = value_range('0', ':'); + const char *str = "0123456789"; + EXPECT_TRUE(std::equal(pair.begin(), pair.end(), str)); +} + +TEST(iterpair, signed8) +{ + IteratorPair> pair = value_range(int8_t(-128), int8_t(127)); + int8_t arr[255] = + { + -128, -127, -126, -125, -124, -123, -122, -121, -120, + -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, + -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, + -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, + -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, + -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, + -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, + -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, + -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, + -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, + -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, + -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, + -9, -8, -7, -6, -5, -4, -3, -2, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, + }; + EXPECT_TRUE(std::equal(pair.begin(), pair.end(), arr + 0)); +} + +TEST(iterpair, unsigned8) +{ + IteratorPair> pair = value_range(uint8_t(0), uint8_t(255)); + uint8_t arr[255] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, + }; + EXPECT_TRUE(std::equal(pair.begin(), pair.end(), arr)); +} diff --git a/src/compat/memory.cpp b/src/compat/memory.cpp new file mode 100644 index 0000000..6a5f526 --- /dev/null +++ b/src/compat/memory.cpp @@ -0,0 +1,3 @@ +#include "memory.hpp" + +#include "../poison.hpp" diff --git a/src/compat/memory.hpp b/src/compat/memory.hpp new file mode 100644 index 0000000..2839640 --- /dev/null +++ b/src/compat/memory.hpp @@ -0,0 +1,27 @@ +#ifndef TMWA_COMPAT_MEMORY_HPP +#define TMWA_COMPAT_MEMORY_HPP + +# include "../sanity.hpp" + +# include + + +template +struct is_array_of_unknown_bound +: std::is_same::type[]> +{}; + +template, class... A> +typename std::enable_if::value, std::unique_ptr>::type make_unique(A&&... a) +{ + return std::unique_ptr(new T(std::forward(a)...)); +} + +template> +typename std::enable_if::value, std::unique_ptr>::type make_unique(size_t sz) +{ + typedef typename std::remove_extent::type E; + return std::unique_ptr(new E[sz]()); +} + +#endif // TMWA_COMPAT_MEMORY_HPP diff --git a/src/compat/nullpo.cpp b/src/compat/nullpo.cpp new file mode 100644 index 0000000..423ed8c --- /dev/null +++ b/src/compat/nullpo.cpp @@ -0,0 +1,28 @@ +#include "nullpo.hpp" + +#include + +#include "../poison.hpp" + +/// Actual output function +static +void nullpo_info(const char *file, int line, const char *func) +{ + if (!file) + file = "??"; + if (!func || !*func) + func = "unknown"; + + fprintf(stderr, "%s:%d: in func `%s': NULL pointer\n", + file, line, func); +} + +bool nullpo_chk(const char *file, int line, const char *func, + const void *target) +{ + if (target) + return 0; + + nullpo_info(file, line, func); + return 1; +} diff --git a/src/compat/nullpo.hpp b/src/compat/nullpo.hpp new file mode 100644 index 0000000..6eca4b6 --- /dev/null +++ b/src/compat/nullpo.hpp @@ -0,0 +1,41 @@ +/// return wrappers for unexpected NULL pointers +#ifndef TMWA_COMPAT_NULLPO_HPP +#define TMWA_COMPAT_NULLPO_HPP +/// Uncomment this to live dangerously +/// (really exist to detect mostly-unused variables) +//# define BUG_FREE + +/// All functions print to standard error (was: standard output) +/// nullpo_ret(cond) - return 0 if given pointer is NULL +/// nullpo_retv(cond) - just return (function returns void) +/// nullpo_retr(rv, cond) - return given value instead + +# ifndef BUG_FREE +# define nullpo_retr(ret, t) \ + if (nullpo_chk(__FILE__, __LINE__, __PRETTY_FUNCTION__, t)) \ + return ret; +# else // BUG_FREE +# define nullpo_retr(ret, t) /*t*/ +# endif // BUG_FREE + +# define nullpo_ret(t) nullpo_retr(0, t) +# define nullpo_retv(t) nullpo_retr(, t) + +# include "../sanity.hpp" + +/// Used by macros in this header +bool nullpo_chk(const char *file, int line, const char *func, + const void *target); + +template +bool nullpo_chk(const char *file, int line, const char *func, T target) +{ + return nullpo_chk(file, line, func, target.operator->()); +} +template +bool nullpo_chk(const char *file, int line, const char *func, T *target) +{ + return nullpo_chk(file, line, func, static_cast(target)); +} + +#endif // TMWA_COMPAT_NULLPO_HPP diff --git a/src/compat/rawmem.cpp b/src/compat/rawmem.cpp new file mode 100644 index 0000000..9e353e8 --- /dev/null +++ b/src/compat/rawmem.cpp @@ -0,0 +1,3 @@ +#include "rawmem.hpp" + +#include "../poison.hpp" diff --git a/src/compat/rawmem.hpp b/src/compat/rawmem.hpp new file mode 100644 index 0000000..ac08964 --- /dev/null +++ b/src/compat/rawmem.hpp @@ -0,0 +1,30 @@ +#ifndef TMWA_COMPAT_RAWMEM_HPP +#define TMWA_COMPAT_RAWMEM_HPP + +# include +# include +# include + +inline +void really_memcpy(uint8_t *dest, const uint8_t *src, size_t n) +{ + memcpy(dest, src, n); +} + +inline +void really_memmove(uint8_t *dest, const uint8_t *src, size_t n) +{ + memmove(dest, src, n); +} +inline +bool really_memequal(const uint8_t *a, const uint8_t *b, size_t n) +{ + return memcmp(a, b, n) == 0; +} + +inline +void really_memset0(uint8_t *dest, size_t n) +{ + memset(dest, '\0', n); +} +#endif // TMWA_COMPAT_RAWMEM_HPP -- cgit v1.2.3-60-g2f50