diff --git a/include/exiv2/slice.hpp b/include/exiv2/slice.hpp new file mode 100644 index 00000000..c26d058a --- /dev/null +++ b/include/exiv2/slice.hpp @@ -0,0 +1,726 @@ +// ********************************************************* -*- C++ -*- +/* + * Copyright (C) 2004-2018 Exiv2 maintainers + * + * This program is part of the Exiv2 distribution. + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/*! + @file slice.hpp + @brief Simple implementation of slices (=views) for STL containers and C-arrays + @author Dan Čermák (D4N) + dan.cermak@cgc-instruments.com + @date 30-March-18, D4N: created + */ + +#ifndef EXIV2_INCLUDE_SLICE_HPP +#define EXIV2_INCLUDE_SLICE_HPP + +#include +#include +#include +#include + +namespace Exiv2 +{ + namespace Internal + { + // TODO: remove these custom implementations once we have C++11 + template + struct remove_const + { + typedef T type; + }; + + template + struct remove_const + { + typedef T type; + }; + + template + struct remove_volatile + { + typedef T type; + }; + template + struct remove_volatile + { + typedef T type; + }; + template + struct remove_cv + { + typedef typename remove_const::type>::type type; + }; + + template + struct remove_pointer + { + typedef T type; + }; + + template + struct remove_pointer + { + typedef T type; + }; + + template + struct remove_pointer + { + typedef T type; + }; + + /*! + * Common base class of all slice implementations. + * + * Implements only the most basic functions, which do not require any + * knowledge about the stored data. + */ + struct SliceBase + { + inline SliceBase(size_t begin, size_t end) : begin_(begin), end_(end) + { + if (begin >= end) { + throw std::out_of_range("Begin must be smaller than end"); + } + } + + /*! + * Return the number of elements in the slice. + */ + inline size_t size() const throw() + { + // cannot underflow, as we know that begin < end + return end_ - begin_; + } + + protected: + /*! + * Throw an exception when index is too large. + * + * @throw std::out_of_range when `index` will access an element + * outside of the slice + */ + inline void rangeCheck(size_t index) const + { + if (index >= size()) { + throw std::out_of_range("Index outside of the slice"); + } + } + + /*! + * lower and upper bounds of the slice with respect to the + * container/array stored in storage_ + */ + const size_t begin_, end_; + }; + + /*! + * @brief This class provides the public-facing const-qualified methods + * of a slice. + * + * The public methods are implemented in a generic fashion using a + * storage_type. This type contains the actual reference to the data to + * which the slice points and provides the following methods: + * + * - (const) value_type& unsafeAt(size_t index) (const) + * Return the value at the given index of the underlying container, + * without promising to perform a range check and without any + * knowledge of the slices' size + * + * - const_iterator/iterator unsafeGetIteratorAt(size_t index) (const) + * Return a (constant) iterator at the given index of the underlying + * container. Again, no range checks are promised. + * + * - Constructor(data_type& data, size_t begin, size_t end) + * Can use `begin` & `end` to perform range checks on `data`, but + * should not store both values. Must not take ownership of `data`! + * + * - Must save data as a public member named `data_`. + * + * - Must provide appropriate typedefs for iterator, const_iterator and + * value_type + */ + template