Skip to content

Commit

Permalink
GSL implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mbasaglia committed Sep 26, 2015
1 parent 6ed44d3 commit 8dd4cf7
Show file tree
Hide file tree
Showing 6 changed files with 705 additions and 0 deletions.
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

add_subdirectory(test)
302 changes: 302 additions & 0 deletions include/misclib/gsl.hpp
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef MISCLIB_GSL_HPP
#define MISCLIB_GSL_HPP

#include <memory>
#include <array>
#include <vector>
#include <stdexcept>
#include <utility>
#include <iterator>
#include <type_traits>

#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<class T>
using owner = T;

template<class T>
constexpr owner<T> move_owner(owner<T>&& owner)
{
return std::move(owner);
}

using zstring = char*;
using czstring = const char*;

using std::unique_ptr;
using std::shared_ptr;

template<class T, std::size_t size>
using stack_array = std::array<T, size>;

/// \todo
template<class T>
using dyn_array = std::vector<T>;


/// \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 T>
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<T>()) 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 T>
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<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using difference_type = typename std::iterator_traits<iterator>::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<std::size_t size>
CONSTEXPR14 array_view(T (&array)[size])
: array_view(array, size)
{}

template<class Iterator, class =
typename std::enable_if<
std::is_same<typename Iterator::value_type, value_type>::value
>::type>
array_view(const Iterator& begin, const Iterator& end)
: array_view(&*begin, &*end)
{
Expects(std::distance(begin, end) == &*end - &*begin);
}

template<class Container, class =
typename std::enable_if<
std::is_same<typename Container::value_type, value_type>::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 T>
class array_view_p;

using string_view = array_view<char>;
using cstring_view = array_view<const char>;

template<class Functor>
class Final_act
{
public:
explicit Final_act(const Functor& func) : func(func) {}
~Final_act() { func(); }

private:
Functor func;
};

template<class Functor>
inline Final_act<Functor> finally(const Functor& func)
{
return Final_act<Functor>(func);
}

template<class T, class U>
T narrow_cast(U value)
{
return static_cast<T>(value);
}

class narrowing_error : public std::exception {};

template<class T, class U>
T narrow(U value)
{
auto narrowed = narrow_cast<T>(value);
if ( !(narrowed == value) )
throw narrowing_error{};
return narrowed;
}

#define implicit

} // namespace gsl
#endif // MISCLIB_GSL_HPP
Loading

0 comments on commit 8dd4cf7

Please sign in to comment.