diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..65b6ae8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2015 Mattia Basaglia
+#
+# 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 .
+
+add_subdirectory(test)
diff --git a/include/misclib/gsl.hpp b/include/misclib/gsl.hpp
new file mode 100644
index 0000000..5dd4071
--- /dev/null
+++ b/include/misclib/gsl.hpp
@@ -0,0 +1,302 @@
+/**
+ * \file
+ *
+ * \author Mattia Basaglia
+ *
+ * \copyright Copyright (C) 2015 Mattia Basaglia
+ *
+ * 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 .
+ */
+#ifndef MISCLIB_GSL_HPP
+#define MISCLIB_GSL_HPP
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
+# define CONSTEXPR14 constexpr
+#else
+# define CONSTEXPR14
+#endif
+
+/**
+ * \brief A simple GSL implementation for C++11 (and C++14)
+ * \see https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gsl-guideline-support-library
+ */
+namespace gsl {
+
+template
+ using owner = T;
+
+template
+ constexpr owner move_owner(owner&& owner)
+ {
+ return std::move(owner);
+ }
+
+using zstring = char*;
+using czstring = const char*;
+
+using std::unique_ptr;
+using std::shared_ptr;
+
+template
+ using stack_array = std::array;
+
+/// \todo
+template
+ using dyn_array = std::vector;
+
+
+/// \todo Macros to disable expression evaluation
+inline CONSTEXPR14 void Expects(bool expression, czstring message = nullptr)
+{
+ if ( !expression )
+ throw std::logic_error(message ? message : "");
+}
+
+inline CONSTEXPR14 void Ensures(bool expression, czstring message = nullptr)
+{
+ if ( !expression )
+ throw std::logic_error(message ? message : "");
+}
+
+template
+ class not_null
+{
+public:
+ CONSTEXPR14 explicit not_null(const T& ptr)
+ : ptr(ptr)
+ {
+ Expects(this->ptr != nullptr);
+ }
+ CONSTEXPR14 explicit not_null(T&& ptr)
+ : ptr(std::move(ptr))
+ {
+ Expects(this->ptr != nullptr);
+ }
+ not_null(const std::nullptr_t&) = delete;
+ not_null(int) = delete;
+ not_null(const not_null &other) = default;
+ not_null(not_null &&other) = default;
+
+ CONSTEXPR14 not_null& operator=(const T& ptr)
+ {
+ Expects(ptr != nullptr);
+ this->ptr = ptr;
+ return *this;
+ }
+ CONSTEXPR14 not_null& operator=(T&& ptr)
+ {
+ Expects(ptr != nullptr);
+ this->ptr = std::move(ptr);
+ return *this;
+ }
+ not_null& operator=(const std::nullptr_t&) = delete;
+ not_null& operator=(int) = delete;
+ CONSTEXPR14 not_null& operator=(const not_null &other) = default;
+ CONSTEXPR14 not_null& operator=(not_null &&other) = default;
+
+ CONSTEXPR14 operator T() const { return ptr; }
+ CONSTEXPR14 T operator->() const { return ptr; }
+ CONSTEXPR14 decltype(*std::declval()) operator*() const { return *ptr; }
+
+ CONSTEXPR14 bool operator==(const T& rhs) const { return ptr == rhs; }
+ CONSTEXPR14 bool operator!=(const T& rhs) const { return !(*this == rhs); }
+
+private:
+ T ptr;
+};
+
+template
+ class array_view
+{
+public:
+ using value_type = T;
+ using reference = value_type&;
+ using pointer = value_type*;
+ using iterator = T*;
+ using const_iterator = const T*;
+ using reverse_iterator = std::reverse_iterator;
+ using const_reverse_iterator = std::reverse_iterator;
+ using difference_type = typename std::iterator_traits::difference_type;
+ using size_type = std::size_t;
+
+ CONSTEXPR14 array_view(pointer begin, pointer end)
+ : begin_(begin), end_(end)
+ {
+ Expects(begin <= end);
+ }
+
+ CONSTEXPR14 array_view(pointer begin, size_type size)
+ : begin_(begin), end_(begin+size)
+ {
+ Expects(size == 0 || (size > 0 && begin != nullptr));
+ }
+
+ constexpr array_view()
+ : begin_(nullptr), end_(nullptr)
+ {
+ }
+
+ template
+ CONSTEXPR14 array_view(T (&array)[size])
+ : array_view(array, size)
+ {}
+
+ template::value
+ >::type>
+ array_view(const Iterator& begin, const Iterator& end)
+ : array_view(&*begin, &*end)
+ {
+ Expects(std::distance(begin, end) == &*end - &*begin);
+ }
+
+ template::value
+ >::type>
+ array_view(Container& container)
+ : array_view(container.data(), container.size())
+ {
+ }
+
+ constexpr size_type size() const
+ {
+ return end_ - begin_;
+ }
+
+ constexpr bool empty() const
+ {
+ return end_ == begin_;
+ }
+
+ CONSTEXPR14 reference operator[] (size_type i) const
+ {
+ Expects(i >= 0 && i < size());
+ return begin_[i];
+ }
+
+ constexpr explicit operator bool() const
+ {
+ return begin_;
+ }
+
+ constexpr iterator begin() const
+ {
+ return begin_;
+ }
+
+ constexpr iterator end() const
+ {
+ return end_;
+ }
+
+ constexpr const_iterator cbegin() const
+ {
+ return begin_;
+ }
+
+ constexpr const_iterator cend() const
+ {
+ return end_;
+ }
+
+ constexpr const_iterator rbegin() const
+ {
+ return reverse_iterator(end_);
+ }
+
+ constexpr const_iterator rend() const
+ {
+ return reverse_iterator(begin_);
+ }
+
+ constexpr const_reverse_iterator crbegin() const
+ {
+ return reverse_iterator(cbegin());
+ }
+
+ constexpr const_reverse_iterator crend() const
+ {
+ return reverse_iterator(cbegin());
+ }
+
+ constexpr bool operator== (const array_view& rhs) const
+ {
+ return begin_ == rhs.begin_ && end_ == rhs.end_;
+ }
+
+ constexpr bool operator!= (const array_view& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+private:
+ T* begin_;
+ T* end_;
+};
+
+/// \todo
+template
+ class array_view_p;
+
+using string_view = array_view;
+using cstring_view = array_view;
+
+template
+ class Final_act
+{
+public:
+ explicit Final_act(const Functor& func) : func(func) {}
+ ~Final_act() { func(); }
+
+private:
+ Functor func;
+};
+
+template
+ inline Final_act finally(const Functor& func)
+ {
+ return Final_act(func);
+ }
+
+template
+ T narrow_cast(U value)
+ {
+ return static_cast(value);
+ }
+
+class narrowing_error : public std::exception {};
+
+template
+ T narrow(U value)
+ {
+ auto narrowed = narrow_cast(value);
+ if ( !(narrowed == value) )
+ throw narrowing_error{};
+ return narrowed;
+ }
+
+#define implicit
+
+} // namespace gsl
+#endif // MISCLIB_GSL_HPP
diff --git a/include/misclib/math.hpp b/include/misclib/math.hpp
new file mode 100644
index 0000000..c959d33
--- /dev/null
+++ b/include/misclib/math.hpp
@@ -0,0 +1,110 @@
+/**
+ * \file
+ *
+ * \author Mattia Basaglia
+ *
+ * \copyright Copyright (C) 2015 Mattia Basaglia
+ *
+ * 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 .
+ */
+#ifndef MISCLIB_MATH_HPP
+#define MISCLIB_MATH_HPP
+
+#include
+
+namespace math {
+
+/**
+ * \brief Maximum between two values
+ */
+template
+ inline constexpr T max(T&& a, T&& b)
+ {
+ return a < b ? b : a;
+ }
+
+/**
+ * \brief Maximum among several values
+ */
+template
+ inline constexpr T max(T&& a, Ts&&... b)
+ {
+ return max(std::forward(a), max(std::forward(b)...));
+ }
+
+/**
+ * \brief Minimum between two values
+ */
+template
+ inline constexpr T min(T&& a, T&& b)
+ {
+ return !(a < b) ? b : a;
+ }
+
+/**
+ * \brief Minimum among several values
+ */
+template
+ inline constexpr T min(T&& a, Ts&&... b)
+ {
+ return min(std::forward(a), min(std::forward(b)...));
+ }
+
+/**
+ * \brief Absolute value
+ */
+template
+ inline constexpr T abs(T&& x)
+ {
+ return x < 0 ? -x : x;
+ }
+
+/**
+ * \brief Limit \p value to be in [min_value, max_value]
+ * \pre min_value < max_value
+ * \post value in [min_value, max_value]
+ */
+template
+ inline constexpr T bound(T&& min_value, T&& value, T&& max_value)
+ {
+ return max(std::forward(min_value),
+ min(std::forward(value), std::forward(max_value))
+ );
+ }
+
+/**
+ * \brief Normalize a value
+ * \pre value in [min, max] && min < max
+ * \post value in [0, 1]
+ */
+template
+ inline constexpr Real normalize(Real value, Real min, Real max)
+{
+ return (value - min) / (max - min);
+}
+
+/**
+ * \brief Denormalize a value
+ * \pre value in [0, 1] && min < max
+ * \post value in [min, max]
+ */
+template
+ inline constexpr Real denormalize(Real value, Real min, Real max)
+{
+ return value * (max - min) + min;
+}
+
+
+} // namespace math
+#endif // MISCLIB_MATH_HPP
diff --git a/include/misclib/util.hpp b/include/misclib/util.hpp
new file mode 100644
index 0000000..a0fe7e1
--- /dev/null
+++ b/include/misclib/util.hpp
@@ -0,0 +1,77 @@
+/**
+ * \file
+ *
+ * \author Mattia Basaglia
+ *
+ * \copyright Copyright (C) 2015 Mattia Basaglia
+ *
+ * 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 .
+ */
+#ifndef MISCLIB_UTIL_HPP
+#define MISCLIB_UTIL_HPP
+
+#include
+#include
+
+namespace util {
+
+/**
+ * \brief Utility to get a cleaner syntax when disambiguating function pointers
+ */
+template
+ auto overload(R (C::*f)(Args...)) -> R (C::*)(Args...)
+ {
+ return f;
+ }
+
+/**
+ * \brief Determine the distance between a data member and its object
+ */
+template
+ std::size_t offset_of(const Class* object, Type Class::* member)
+ {
+ return reinterpret_cast(&(object->*member)) -
+ reinterpret_cast(object);
+ }
+
+/**
+ * \brief Template to retrieve information about a function signature
+ *
+ * Use as FunctionSignature or FunctionSignature
+ */
+template
+ struct FunctionSignature;
+
+template
+ struct FunctionSignature
+ {
+ using pointer_type = Ret (*) (Args...);
+ using return_type = Ret;
+ using arguments_types = std::tuple;
+ };
+
+template
+ struct FunctionSignature
+ : public FunctionSignature
+ {
+ };
+
+/**
+ * \brief Clean syntax to get a function pointer type
+ */
+template
+ using FunctionPointer = typename FunctionSignature::pointer_type;
+
+} // namespace util
+#endif // MISCLIB_UTIL_HPP
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..e2dc8b8
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,64 @@
+# Copyright (C) 2015 Mattia Basaglia
+#
+# 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(CTest)
+
+set(Boost_FOUND ON)
+
+# Boost
+find_package (Boost COMPONENTS unit_test_framework)
+
+#Tests
+if (Boost_FOUND)
+
+include_directories (${Boost_INCLUDE_DIRS})
+add_definitions (-DBOOST_TEST_DYN_LINK)
+
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address --coverage -O0 -fno-inline")
+set(MISCLIB_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../include/misclib")
+include_directories(${MISCLIB_SOURCES}/..)
+
+message(STATUS "Test targets for Misclib enabled")
+enable_testing()
+
+set(TEST_TARGETS "")
+function(test test_name)
+ add_executable(${test_name} EXCLUDE_FROM_ALL ${ARGN})
+ target_link_libraries(${test_name} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ add_test (NAME ${test_name} COMMAND ${test_name})
+ set(TEST_TARGETS ${TEST_TARGETS} ${test_name} PARENT_SCOPE)
+endfunction(test)
+
+test(misclib_test_gsl ${MISCLIB_SOURCES}/gsl.hpp gsl.cpp)
+
+# Coverage
+add_custom_target(misclib_test_all
+ DEPENDS ${TEST_TARGETS}
+ COMMENT "Building all tests"
+)
+
+set(TRACEFILE "${CMAKE_CURRENT_BINARY_DIR}/coverage.info")
+add_custom_target(misclib_coverage
+ COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}"
+ COMMAND ctest -V
+ COMMAND lcov -c -d "${CMAKE_CURRENT_BINARY_DIR}" -b "${MISCLIB_SOURCES}" -o ${TRACEFILE} --no-external
+ COMMAND genhtml ${TRACEFILE} -o "${CMAKE_CURRENT_BINARY_DIR}/lconv" -p "${MISCLIB_SOURCES}" --demangle-cpp
+ DEPENDS ${TEST_TARGETS}
+)
+
+add_custom_target(misclib_coverage_view
+ COMMAND xdg-open "${CMAKE_CURRENT_BINARY_DIR}/lconv/index.html"
+)
+
+endif()
diff --git a/test/gsl.cpp b/test/gsl.cpp
new file mode 100644
index 0000000..b91c5f9
--- /dev/null
+++ b/test/gsl.cpp
@@ -0,0 +1,136 @@
+/**
+ * \file
+ *
+ * \author Mattia Basaglia
+ *
+ * \copyright Copyright (C) 2015 Mattia Basaglia
+ *
+ * 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 .
+ *
+ */
+
+#define BOOST_TEST_MODULE Test_Formatter
+
+#include
+
+#include "misclib/gsl.hpp"
+#include
+#include
+#include
+#include
+
+BOOST_AUTO_TEST_CASE( test_owner )
+{
+ gsl::owner owner = new int{42};
+ BOOST_CHECK(owner);
+ BOOST_CHECK(*owner == 42);
+ int* not_owner = owner;
+ BOOST_CHECK(*not_owner == 42);
+ BOOST_CHECK(not_owner == owner);
+ delete owner;
+}
+
+unsigned subtract(unsigned a, unsigned b)
+{
+ gsl::Expects(b > 0);
+ auto r = a - b;
+ gsl::Ensures(r < a);
+ return r;
+}
+
+BOOST_AUTO_TEST_CASE( test_pre_post )
+{
+ BOOST_CHECK(subtract(5, 4) == 1);
+ BOOST_CHECK_THROW(subtract(5, 0), std::exception);
+ BOOST_CHECK_THROW(subtract(5, 6), std::exception);
+}
+
+BOOST_AUTO_TEST_CASE( test_not_null )
+{
+ int* null = nullptr;
+ int val = 5;
+ int* not_null = &val;
+ gsl::not_null ptr(&val);
+ int* maybe_null;
+ BOOST_CHECK_THROW( gsl::not_null foo(null), std::exception);
+ BOOST_CHECK( gsl::not_null(not_null) == not_null );
+ BOOST_CHECK( ptr );
+ BOOST_CHECK( *ptr == val );
+ BOOST_CHECK( ptr == &val );
+ BOOST_CHECK( ptr != null );
+ BOOST_CHECK_THROW( ptr = null, std::exception);
+ BOOST_CHECK( ptr = not_null );
+ BOOST_CHECK( ptr == &val );
+ BOOST_CHECK( maybe_null = ptr );
+ BOOST_CHECK( *maybe_null = val );
+ /// \todo Test with smart pointers
+}
+
+int fifth(const gsl::array_view& array)
+{
+ return array[5];
+}
+
+BOOST_AUTO_TEST_CASE( test_array_view )
+{
+ using array_view = gsl::array_view;
+ std::vector intv = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ std::array inta = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ std::list intl = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ int intca[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ BOOST_CHECK(fifth(intv) == 6);
+ BOOST_CHECK(fifth(inta) == 6);
+ BOOST_CHECK(fifth(intca) == 6);
+ BOOST_CHECK(fifth({intca, 8}) == 6);
+ BOOST_CHECK_THROW(fifth({intl.begin(), intl.end()}), std::exception);
+ BOOST_CHECK_THROW(fifth({intca, 4}), std::exception);
+
+ array_view view = intv;
+ array_view view2{intv.begin(), intv.end()};
+ BOOST_CHECK(view);
+ BOOST_CHECK(view.begin() == &intv.front());
+ BOOST_CHECK(view.end() == &intv.back()+1);
+ BOOST_CHECK(view.size() == intv.size());
+ BOOST_CHECK(view == view2);
+ view = inta;
+ BOOST_CHECK(view.begin() == &inta.front());
+ BOOST_CHECK(view.end() == &inta.back()+1);
+ BOOST_CHECK(view.size() == inta.size());;
+ BOOST_CHECK(view != view2);
+ view = {intca, std::size_t(0)};
+ BOOST_CHECK(view.begin() == intca);
+ BOOST_CHECK(view.size() == 0);
+}
+
+BOOST_AUTO_TEST_CASE( test_finally )
+{
+ int i = 0;
+ auto lambda = [&i]{++i;};
+
+ {
+ auto f = gsl::finally(lambda);
+ BOOST_CHECK(i == 0);
+ }
+
+ BOOST_CHECK(i == 1);
+}
+
+BOOST_AUTO_TEST_CASE( test_narrow )
+{
+ long big = std::numeric_limits::max();
+ big *= 2;
+ BOOST_CHECK_THROW(gsl::narrow(big), gsl::narrowing_error);
+ BOOST_CHECK(gsl::narrow(big) == big);
+}