/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #ifndef INCLUDED_BASEBMP_METAFUNCTIONS_HXX #define INCLUDED_BASEBMP_METAFUNCTIONS_HXX #include #include #include #include namespace basebmp { // TODO(Q3): move to generic place (o3tl?) /** template meta function: add const qualifier to 2nd type, if given 1st type has it */ template struct clone_const { typedef B type; }; template struct clone_const { typedef const B type; }; /** template meta function: add const qualifier to plain type (if not already there) */ template struct add_const { typedef const T type; }; template struct add_const { typedef const T type; }; /// template meta function: remove const qualifier from plain type template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; //-------------------------------------------------------------- /// Base class for an adaptable ternary functor template< typename A1, typename A2, typename A3, typename R > struct TernaryFunctorBase { typedef A1 first_argument_type; typedef A2 second_argument_type; typedef A3 third_argument_type; typedef R result_type; }; //-------------------------------------------------------------- /** template meta function: ensure that given integer type is unsigned If given integer type is already unsigned, return as-is - otherwise, convert to unsigned type of same or greater range. */ template< typename T > struct make_unsigned; #define BASEBMP_MAKE_UNSIGNED(T,U) \ template<> struct make_unsigned { \ typedef U type; \ }; BASEBMP_MAKE_UNSIGNED(signed char,unsigned char) BASEBMP_MAKE_UNSIGNED(unsigned char,unsigned char) BASEBMP_MAKE_UNSIGNED(short,unsigned short) BASEBMP_MAKE_UNSIGNED(unsigned short,unsigned short) BASEBMP_MAKE_UNSIGNED(int,unsigned int) BASEBMP_MAKE_UNSIGNED(unsigned int,unsigned int) BASEBMP_MAKE_UNSIGNED(long,unsigned long) BASEBMP_MAKE_UNSIGNED(unsigned long,unsigned long) #undef BASEBMP_MAKE_UNSIGNED /// cast integer to unsigned type of similar size template< typename T > inline typename make_unsigned::type unsigned_cast( T value ) { return static_cast< typename make_unsigned::type >(value); } //-------------------------------------------------------------- /// returns true, if given number is strictly less than 0 template< typename T > inline bool is_negative( T x ) { return x < 0; } /// Overload for ints (branch-free) inline bool is_negative( int x ) { // force logic shift (result for signed shift right is undefined) return static_cast(x) >> (sizeof(int)*8-1); } //-------------------------------------------------------------- /// Results in VigraTrueType, if T is of integer type and scalar template< typename T, typename trueCase, typename falseCase > struct ifScalarIntegral { typedef typename vigra::If< typename vigra::NumericTraits< T >::isIntegral, typename vigra::If< typename vigra::NumericTraits< T >::isScalar, trueCase, falseCase >::type, falseCase >::type type; }; /// Results in VigraTrueType, if T is of non-integer type and scalar template< typename T, typename trueCase, typename falseCase > struct ifScalarNonIntegral { typedef typename vigra::If< typename vigra::NumericTraits< T >::isIntegral, falseCase, typename vigra::If< typename vigra::NumericTraits< T >::isScalar, trueCase, falseCase >::type >::type type; }; /// Results in VigraTrueType, if both T1 and T2 are of integer type and scalar template< typename T1, typename T2, typename trueCase, typename falseCase > struct ifBothScalarIntegral { typedef typename ifScalarIntegral< T1, typename ifScalarIntegral< T2, trueCase, falseCase >::type, falseCase >::type type; }; //-------------------------------------------------------------- /// Count number of trailing zeros template< unsigned int val > struct numberOfTrailingZeros { enum { next = val >> 1 }; enum { value = vigra::IfBool< (val & 1) == 0, numberOfTrailingZeros, boost::mpl::integral_c< int,-1 > > ::type::value + 1 }; }; template<> struct numberOfTrailingZeros<0> { enum { value = 0 }; }; //-------------------------------------------------------------- /// Count number of one bits template< unsigned int val > struct bitcount { enum { next = val >> 1 }; enum { value = bitcount::value + (val & 1) }; }; template<> struct bitcount<0> { enum { value = 0 }; }; //-------------------------------------------------------------- /// Shift left for positive shift value, and right otherwise template< typename T > inline T shiftLeft( T v, int shift ) { return shift > 0 ? v << shift : v >> (-shift); } /// Shift right for positive shift value, and left otherwise template< typename T > inline T shiftRight( T v, int shift ) { return shift > 0 ? v >> shift : v << (-shift); } //-------------------------------------------------------------- /// Replace non-std project2nd from SGI extensions template< typename T1, typename T2 > struct project2nd : public std::binary_function { T2 operator() (const T1&, const T2& v) const { return v; } }; } // namespace basebmp #endif /* INCLUDED_BASEBMP_METAFUNCTIONS_HXX */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */