Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed_DS28EC20_GPIO
Segment.hpp
00001 /******************************************************************************* 00002 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #ifndef MaximInterface_Segment 00034 #define MaximInterface_Segment 00035 00036 #include <iterator> 00037 #include <utility> 00038 #include "type_traits.hpp" 00039 00040 namespace MaximInterface { 00041 00042 /// @brief 00043 /// Advances a given iterator by a given number of elements with bounds checking. 00044 /// @tparam InputIt Must meet the requirements of InputIterator. 00045 /// @param[in,out] it Iterator to advance. 00046 /// @param bound 00047 /// Past-the-end boundary iterator. If distance is positive, bound must be 00048 /// reachable by incrementing the given iterator. If distance is negative, bound 00049 /// must be reachable by decrementing the given iterator. 00050 /// @param distance 00051 /// Number of elements to advance the given iterator. If distance is positive, 00052 /// the given iterator is incremented. If distance is negative, the given 00053 /// iterator is decremented, and InputIt must meet the requirements of 00054 /// BidirectionalIterator. 00055 /// @returns The number of elements that the given iterator was advanced. 00056 template <typename InputIt> 00057 typename std::iterator_traits<InputIt>::difference_type checkedAdvance( 00058 InputIt & it, const InputIt bound, 00059 typename std::iterator_traits<InputIt>::difference_type distance) { 00060 typedef 00061 typename std::iterator_traits<InputIt>::difference_type difference_type; 00062 00063 // Use constant-time operations if InputIt is a random access iterator. 00064 if (is_same<typename std::iterator_traits<InputIt>::iterator_category, 00065 std::random_access_iterator_tag>::value) { 00066 const difference_type boundDistance = std::distance(it, bound); 00067 if (boundDistance >= 0) { 00068 if (distance > boundDistance) { 00069 distance = boundDistance; 00070 } else if (distance < 0) { 00071 distance = 0; 00072 } 00073 } else { 00074 if (distance < boundDistance) { 00075 distance = boundDistance; 00076 } else if (distance > 0) { 00077 distance = 0; 00078 } 00079 } 00080 std::advance(it, distance); 00081 } else { 00082 const difference_type startingDistance = distance; 00083 while (distance != 0 && it != bound) { 00084 if (distance > 0) { 00085 ++it; 00086 --distance; 00087 } else { 00088 --it; 00089 ++distance; 00090 } 00091 } 00092 if (startingDistance > 0) { 00093 distance = startingDistance - distance; 00094 } else { 00095 distance = startingDistance + distance; 00096 } 00097 } 00098 return distance; 00099 } 00100 00101 /// @brief Locates an iterator sub-range using segment number addressing. 00102 /// @details 00103 /// Useful for devices that divide the memory space into uniform chunks such as 00104 /// pages and segments. 00105 /// @tparam ForwardIt Must meet the requirements of ForwardIterator. 00106 /// @param begin Beginning of the input data range. 00107 /// @param end End of the input data range. 00108 /// @param segmentSize Number of elements contained in a segment. 00109 /// @param segmentNum Zero-indexed number of the desired segment. 00110 /// @returns 00111 /// Pair of iterators representing the sub-range of the segment within 00112 /// the input range. If the segment does not exist within the input range, both 00113 /// iterators in the pair are set to the end iterator of the input range. 00114 template <typename ForwardIt, typename Index> 00115 std::pair<ForwardIt, ForwardIt> createSegment( 00116 ForwardIt begin, const ForwardIt end, 00117 const typename std::iterator_traits<ForwardIt>::difference_type segmentSize, 00118 Index segmentNum) { 00119 ForwardIt segmentEnd = begin; 00120 typename std::iterator_traits<ForwardIt>::difference_type lastSegmentSize = 00121 checkedAdvance(segmentEnd, end, segmentSize); 00122 while (segmentNum > 0 && segmentEnd != end) { 00123 begin = segmentEnd; 00124 lastSegmentSize = checkedAdvance(segmentEnd, end, segmentSize); 00125 --segmentNum; 00126 } 00127 if (segmentNum > 0 || lastSegmentSize != segmentSize) { 00128 begin = segmentEnd; 00129 } 00130 return std::make_pair(begin, segmentEnd); 00131 } 00132 00133 } // namespace MaximInterface 00134 00135 #endif
Generated on Tue Jul 12 2022 23:29:45 by
1.7.2