From 91e63687b847951ec7d4f494fe64518168437301 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 20 Jun 2018 16:18:07 +0200 Subject: [PATCH] start documentation of std module --- alib2std/src/extensions/algorithm.hpp | 164 ++++++++++++++++++++++++++ alib2std/src/extensions/allocFix.hpp | 24 ++++ alib2std/src/extensions/array.hpp | 109 ++++++++++++++++- 3 files changed, 292 insertions(+), 5 deletions(-) diff --git a/alib2std/src/extensions/algorithm.hpp b/alib2std/src/extensions/algorithm.hpp index 9c42f5b544..9c48cc8bdc 100644 --- a/alib2std/src/extensions/algorithm.hpp +++ b/alib2std/src/extensions/algorithm.hpp @@ -1,6 +1,22 @@ /* * algorithm.hpp * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit 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. + + * Algorithms library toolkit 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 Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: May 28, 2015 * Author: Jan Travnicek */ @@ -13,6 +29,19 @@ namespace ext { +/** + * Tests two sorted ranges wheter all elements from the second are not present in the first. + * + * Complexity linear in minimum of sizes of the two ranges. + * + * \param first1 the begining of the first range + * \param first2 the end of the first range + * \param second1 the begining of the second range + * \param second2 the end of the second range + * \param comp the comparator of range elements + * + * \return true if all elements from second range are not in the first, false othervise + */ template<class InputIt1, class InputIt2, class Compare> bool excludes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp) { while (first2 != last2 && first1 != last1) { @@ -27,11 +56,44 @@ bool excludes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, return true; } +/** + * Tests two sorted ranges wheter all elements from the second are not present in the first. + * + * Complexity linear in minimum of sizes of the two ranges. + * + * The elements of the ranges are compared by the default less operator + * + * \param first1 the begining of the first range + * \param first2 the end of the first range + * \param second1 the begining of the second range + * \param second2 the end of the second range + * + * \tparam ImputIt1 type of the first iterator + * \tparam ImputIt2 type of the second iterator + * + * \return true if all elements from second range are not in the first, false othervise + */ template<class InputIt1, class InputIt2> bool excludes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) { return excludes(first1, last1, first2, last2, std::less<decltype(*first1)>()); } +/** + * In container tranformation of all elements according to the \p tranform. + * + * \param in the input container + * \param transform the callback + * + * \tparam ResType the result of the transformation + * \tparam InType the type of original element + * \tparam Ts ... additional types of the in container + * \tparam ContainerType the template parameter of the container + * \tparam Callback the type of the transformation callback + * + * The function needs redesign. Ranges and output iterator should be used instead of container construction. + * + * \return a new container with transformed elements + */ template < class ResType, class InType, typename ... Ts, template < typename ... > class ContainerType, class Callback > ContainerType < ResType > transform(const ContainerType < InType, Ts ... > & in, Callback transform ) { ContainerType<ResType> res; @@ -39,11 +101,35 @@ ContainerType < ResType > transform(const ContainerType < InType, Ts ... > & in, return res; } +/** + * Linear version of search in a range of values. + * + * \param first the beginning of the range + * \param second the end of the range + * \param elem the searched element + * + * \tparam InputIt the type of the iterator + * \tparam Element the type of the searched element + * + * \return true if the elem is inside the range (first, second], false othervise + */ template<class InputIt, class Element> bool contains(InputIt first, InputIt last, const Element& elem) { return find(first, last, elem) != last; } +/** + * Logaritmic version of search in a range of sorted values. + * + * \param first the beginning of the range + * \param second the end of the range + * \param elem the searched element + * + * \tparam InputIt the type of the iterator + * \tparam Element the type of the searched element + * + * \return true if the elem is inside the range (first, second], false othervise + */ template<class InputIt, class Element> bool binary_contains(InputIt first, InputIt last, const Element& elem) { return binary_search(first, last, elem) != last; @@ -77,6 +163,21 @@ inline bool orAll ( T value, Ts ... other ) { return value || orAll ( other ... ); } +/** + * Function to locate pair of iterators (openPos, closePos), i.e. both openPos and closePos are included in the range, where * openPos == \p open and closePos == \p closePos, or openPos = closePos = begin if no range can be found. + * + * The found range either does not contain nested range or the range it contains is recursively satisfying this definition. + * + * In order for the function to find all ranges satisfying the above condition, the range (begin, end] must contain corretly nested ranges delimited by \p open and \p close. + * + * \param begin the begining of the examined range + * \param end the end of the examined range + * \param open the opening parenthesis + * \param end the value of closing parenthesis + * + * \tparam Iterator the type of range denoting iterator + * \tparam Value the type of open and close delimiters + */ template < class Iterator, class Value > std::pair < Iterator, Iterator > __find_range ( Iterator begin, Iterator end, const Value & open, const Value & close ) { for ( ; begin != end && * begin != open && * begin != close ; ++ begin ); @@ -108,6 +209,21 @@ std::pair < Iterator, Iterator > __find_range ( Iterator begin, Iterator end, co return std::make_pair ( openPos, closePos ); } +/** + * Function to locate pair of iterators (openPos, closePos] where * openPos == \p open and closePos == \p closePos, or openPos = closePos = begin if no range can be found. + * + * The found range either does not contain nested range or the range it contains is recursively satisfying this definition. + * + * In order for the function to find all ranges satisfying the above condition, the range (begin, end] must contain corretly nested ranges delimited by \p open and \p close. + * + * \param begin the begining of the examined range + * \param end the end of the examined range + * \param open the opening parenthesis + * \param end the value of closing parenthesis + * + * \tparam Iterator the type of range denoting iterator + * \tparam Value the type of open and close delimiters + */ template < class Iterator, class Value > std::pair < Iterator, Iterator > find_range ( Iterator begin, Iterator end, const Value & open, const Value & close ) { std::pair < Iterator, Iterator > res = __find_range ( begin, end, open, close ); @@ -120,26 +236,71 @@ std::pair < Iterator, Iterator > find_range ( Iterator begin, Iterator end, cons return res; } +/** + * Root case of maximum computation. The maximum from one value is the value itself. + * + * \param a the value to compute maximum from + * + * \tparam T the type of the value to compute maximum from + * + * \return the value a + */ template < typename T > const T & max ( const T & a ) { return a; } +/** + * Root case of maximum computation. The maximum from one value is the value itself. + * + * \param a the first value to compute maximum from + * \param b the second value to compute maximum from + * \param args ... the other values to compute maximum from + * + * \tparam T the type of the values to compute maximum from + * \tparam Args ... type of other values not yet processed here. Technically these types should be same as T + * + * \return the maximum from all values a, b, args ... + */ template < typename T, typename ... Args > const T & max ( const T & a, const T & b, const Args & ... args ) { return max ( b < a ? a : b, args ... ); } +/** + * Root case of minimum computation. The minimum from one value is the value itself. + * + * \param a the value to compute minimum from + * + * \tparam T the type of the value to compute minimum from + * + * \return the value a + */ template < typename T > const T & min ( const T & a) { return a; } +/** + * Root case of minimum computation. The minimum from one value is the value itself. + * + * \param a the first value to compute minimum from + * \param b the second value to compute minimum from + * \param args ... the other values to compute minimum from + * + * \tparam T the type of the values to compute minimum from + * \tparam Args ... type of other values not yet processed here. Technically these types should be same as T + * + * \return the minimum from all values a, b, args ... + */ template < typename T, typename ... Args > const T & min ( const T & a, const T & b, const Args & ... args) { return min ( b > a ? a : b, args ... ); } +/** + * Internal function of standard library. + */ template < typename _ForwardIterator, typename _BinaryPredicate > _ForwardIterator __adjacent_find ( _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred ) { if (__first == __last) @@ -153,6 +314,9 @@ _ForwardIterator __adjacent_find ( _ForwardIterator __first, _ForwardIterator __ return __last; } +/** + * Internal function of standard library tuned to handle swapping of pointers. + */ template < typename _ForwardIterator, typename _BinaryPredicate > _ForwardIterator __unique ( _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred ) { // Skip the beginning, if already unique. diff --git a/alib2std/src/extensions/allocFix.hpp b/alib2std/src/extensions/allocFix.hpp index 71d4d9bd5a..771e1e85a9 100644 --- a/alib2std/src/extensions/allocFix.hpp +++ b/alib2std/src/extensions/allocFix.hpp @@ -1,6 +1,22 @@ /* * allocFix.hpp * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit 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. + + * Algorithms library toolkit 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 Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Mar 6, 2018 * Author: Jan Travnicek */ @@ -9,13 +25,21 @@ #define __ALLOC_FIX_HPP_ // related to issue with 'undefined reference to allocator < ... >::allocator ( )', subject of a delete when g++ fixes the issue +// the undefined reference occurs when one inherits from a class whose constructor has default value for the allocator +// I guess the default parameter construction (allocator constructor) should be inlined but it isn't. Its code is not emited either. namespace ext { +/** + * Class implementing the fix of undefined allocator + * + * TODO test if later versions of g++ are no longer affected. + */ template < class Alloc > class AllocFix { public: AllocFix ( ) { + // just to make sure the allocator constructor exists static Alloc alloc; } }; diff --git a/alib2std/src/extensions/array.hpp b/alib2std/src/extensions/array.hpp index c5ac15073a..136d49744b 100644 --- a/alib2std/src/extensions/array.hpp +++ b/alib2std/src/extensions/array.hpp @@ -1,6 +1,22 @@ /* * array.hpp * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit 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. + + * Algorithms library toolkit 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 Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Apr 1, 2013 * Author: Jan Travnicek */ @@ -19,34 +35,76 @@ namespace ext { +/** + * Class extending the array class from the standard library. Original reason is to allow printing of the container with overloaded operator <<. + * + * The class mimics the behavior of the array from the standatd library. + * + * \tparam T the type of values in the array + * \tparam N the size of the array + */ template < class T, std::size_t N > class array : public std::array < T, N > { public: -#ifdef __clang__ + /** + * Inherit constructors of the standard array + */ using std::array < T, N >::array; + + /** + * Inherit operator = of the standard array + */ using std::array < T, N >::operator =; -#else + +#ifndef __clang__ + + /** + * Default constructor needed by g++ since it is not inherited + */ array ( ) noexcept : std::array < T, N > ( ) { } + /** + * Copy constructor needed by g++ since it is not inherited + */ array ( const array & other ) = default; + /** + * Move constructor needed by g++ since it is not inherited + */ array ( array && other ) = default; - using std::array < T, N >::array; - + /** + * Copy operator = needed by g++ since it is not inherited + */ array & operator = ( array && other ) = default; + /** + * Move operator = needed by g++ since it is not inherited + */ array & operator = ( const array & other ) = default; - using std::array < T, N >::operator =; #endif + /** + * Constructor of array from list of values. + */ template < class ... Types > array ( Types && ... args ) : std::array < T, N > ( std::experimental::make_array ( std::forward < Types > ( args ) ... ) ) { } }; +/** + * Operator to print the array to the output stream. + * + * \param out the output stream + * \param array the array to print + * + * \tparam T the type of values inside the array + * \tparam N the size of the array + * + * \return the output stream from the \p out + */ template< class T, std::size_t N > std::ostream& operator<<(std::ostream& out, const ext::array < T, N > & array) { out << "["; @@ -62,8 +120,23 @@ std::ostream& operator<<(std::ostream& out, const ext::array < T, N > & array) { return out; } +/** + * Specialisation of the compare structure implementing the three-way comparison + * + * \tparam T the type of values inside the array + * \tparam N the size of the array + */ template< class T, std::size_t N > struct compare < ext::array < T, N > > { + + /** + * Implementation of the three-way comparison + * + * \param first the left operand of the comparison + * \param second the right operand of the comparison + * + * \return negative value of left < right, positive value if left > right, zero if left == right + */ int operator ( ) ( const ext::array < T, N > & first, const ext::array < T, N > & second) const { static compare<typename std::decay < T >::type > comp; for(auto iterF = first.begin(), iterS = second.begin(); iterF != first.end(); ++iterF, ++iterS) { @@ -74,6 +147,14 @@ struct compare < ext::array < T, N > > { } }; +/** + * Overload of to_string function. + * + * \param value the value to be converted to string + * + * \tparam T the type of values inside the array + * \tparam N the size of the array + */ template< class T, std::size_t N > std::string to_string ( const ext::array < T, N > & value ) { std::stringstream ss; @@ -81,11 +162,29 @@ std::string to_string ( const ext::array < T, N > & value ) { return ss.str(); } +/** + * Equivalent to the make_array from standard library but produces the ext::array. + * + * \param first the required value of the array + * \param other ... other values to be placed to the array + * + * \tparam Base the type of the first value + * \tparam Types the types of remaining types (they should be the same or convertible to Base type) + * + * \return array containing first and other values of size equal to the number of parameters. + */ template < typename Base, typename ... Types > constexpr array < typename std::remove_reference < Base >::type, sizeof ... ( Types ) + 1 > make_array ( Base && first, Types && ... other ) { return array < typename std::remove_reference < Base >::type, sizeof ... ( Types ) + 1 > ( std::forward < Base > ( first ), std::forward < Types > ( other ) ... ); } +/** + * Special case of make_array handling zero parameters. Technically calls default constructor. + * + * \tparam Base the type of array values + * + * \return array of zero size with the type of values set to Base type. + */ template < typename Base > constexpr array < typename std::remove_reference < Base >::type, 0 > make_array ( ) { return array < typename std::remove_reference < Base >::type, 0 > ( ); -- GitLab