summaryrefslogtreecommitdiff
path: root/src/compat
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-03-15 19:34:59 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-03-16 18:58:48 -0700
commitc812c92d1a1835f0bda783e709481188c8d92225 (patch)
treeb401ede48a088ad1aaed88fe3b997cd26ff7ae08 /src/compat
parentde9ee1b9754af9d954487121947352f32d7ebb7e (diff)
downloadtmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.gz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.bz2
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.xz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.zip
Clean up header organization
Diffstat (limited to 'src/compat')
-rw-r--r--src/compat/alg.cpp3
-rw-r--r--src/compat/alg.hpp21
-rw-r--r--src/compat/attr.hpp13
-rw-r--r--src/compat/cast.cpp3
-rw-r--r--src/compat/cast.hpp54
-rw-r--r--src/compat/fun.hpp11
-rw-r--r--src/compat/iter.cpp3
-rw-r--r--src/compat/iter.hpp97
-rw-r--r--src/compat/iter_test.cpp82
-rw-r--r--src/compat/memory.cpp3
-rw-r--r--src/compat/memory.hpp27
-rw-r--r--src/compat/nullpo.cpp28
-rw-r--r--src/compat/nullpo.hpp41
-rw-r--r--src/compat/rawmem.cpp3
-rw-r--r--src/compat/rawmem.hpp30
15 files changed, 419 insertions, 0 deletions
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 <type_traits>
+
+
+template<class A, class B>
+typename std::common_type<A, B>::type min(A a, B b)
+{
+ return a < b ? a : b;
+}
+
+template<class A, class B>
+typename std::common_type<A, B>::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 <utility>
+# include <type_traits>
+
+
+template<class T>
+const T& const_(T& t)
+{
+ return t;
+}
+
+template<class T, class U>
+T no_cast(U&& u)
+{
+ typedef typename std::remove_reference<T>::type Ti;
+ typedef typename std::remove_reference<U>::type Ui;
+ typedef typename std::remove_cv<Ti>::type Tb;
+ typedef typename std::remove_cv<Ui>::type Ub;
+ static_assert(std::is_same<Tb, Ub>::value, "not no cast");
+ return std::forward<U>(u);
+}
+
+template<class T, class U>
+T base_cast(U&& u)
+{
+ static_assert(std::is_reference<T>::value, "must base cast with references");
+ typedef typename std::remove_reference<T>::type Ti;
+ typedef typename std::remove_reference<U>::type Ui;
+ typedef typename std::remove_cv<Ti>::type Tb;
+ typedef typename std::remove_cv<Ui>::type Ub;
+ static_assert(std::is_base_of<Tb, Ub>::value, "not base cast");
+ return std::forward<U>(u);
+}
+
+// use this when e.g. U is an int of unknown size
+template<class T, class U>
+T maybe_cast(U u)
+{
+ return u;
+}
+
+template<class T, class U>
+typename std::remove_pointer<T>::type *sign_cast(U *u)
+{
+ typedef typename std::remove_pointer<T>::type T_;
+ static_assert(sizeof(T_) == sizeof(U), "sign cast must be same size");
+ return reinterpret_cast<T_ *>(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 <functional>
+
+
+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 <b.r.longbons@gmail.com>
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+# include "../sanity.hpp"
+
+# include <iterator>
+
+
+/// Simple class to use a pair of iterators with foreach
+template<class It>
+class IteratorPair
+{
+ It _b, _e;
+public:
+ IteratorPair(It b, It e)
+ : _b(b), _e(e)
+ {}
+
+ It begin() { return _b; }
+ It end() { return _e; }
+};
+
+template<class It>
+IteratorPair<It> iterator_pair(It b, It e)
+{
+ return {b, e};
+}
+
+template<class T>
+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 T, class Math=PassthroughMath<T>>
+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<class T>
+IteratorPair<ValueIterator<T>> 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 <gtest/gtest.h>
+
+#include "../strings/xstring.hpp"
+
+TEST(iterpair, string)
+{
+ IteratorPair<ValueIterator<char>> pair = value_range('0', ':');
+ const char *str = "0123456789";
+ EXPECT_TRUE(std::equal(pair.begin(), pair.end(), str));
+}
+
+TEST(iterpair, signed8)
+{
+ IteratorPair<ValueIterator<int8_t>> 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<ValueIterator<uint8_t>> 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 <memory>
+
+
+template<class T>
+struct is_array_of_unknown_bound
+: std::is_same<T, typename std::remove_extent<T>::type[]>
+{};
+
+template<class T, class D=std::default_delete<T>, class... A>
+typename std::enable_if<!is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(A&&... a)
+{
+ return std::unique_ptr<T, D>(new T(std::forward<A>(a)...));
+}
+
+template<class T, class D=std::default_delete<T>>
+typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(size_t sz)
+{
+ typedef typename std::remove_extent<T>::type E;
+ return std::unique_ptr<E[], D>(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 <cstdio>
+
+#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<class T>
+bool nullpo_chk(const char *file, int line, const char *func, T target)
+{
+ return nullpo_chk(file, line, func, target.operator->());
+}
+template<class T>
+bool nullpo_chk(const char *file, int line, const char *func, T *target)
+{
+ return nullpo_chk(file, line, func, static_cast<const void *>(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 <cstddef>
+# include <cstdint>
+# include <cstring>
+
+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