<commit_before>#pragma once

#include <iostream>
#include <type_traits> // for std::is_same<>
#include <functional>
#include <type_traits> // for std::false_type/std::true_type
#include <exception> // for std::is_same<>

namespace mittens
{
   //////////////////////////////////////////////////////////////////////////

   template <typename FailCodeType_ = int>
   class UnHandler
   {
   public:
      typedef FailCodeType_ FailCodeType;

      FailCodeType handleException()
      {
         // Instead of a call to `throw` we will check if the function was called inside a
         // catch clause. If so, `std::rethrow_exception(eptr)` is the same as `throw`.
         // Otherwise, throw an `std::logic_error` since this is obviously a bug.
         if (std::exception_ptr eptr = std::current_exception())
            std::rethrow_exception(eptr);

         throw std::logic_error("Mittens handler called outside of a catch clause! This is a BUG.");
      }
      FailCodeType operator()() { return handleException(); }
   };

   //////////////////////////////////////////////////////////////////////////
   // Helper utils
   namespace
   {
      template <bool v> struct Bool2Type { static const bool value = v; };  // anonymous helper function
   }

   // Helper default no-action type
   template <typename ExceptionType = void>
   struct DefaultNoAction
   {  void operator()(ExceptionType&){} };

   template <>
   struct DefaultNoAction<void>
   {  void operator()(){} };

   //////////////////////////////////////////////////////////////////////////

   template <typename ExceptionType, typename NestedHandler, typename Callable = DefaultNoAction<ExceptionType> >
   class GenericExceptionHandler
   {
   public:
      typedef typename NestedHandler::FailCodeType FailCodeType;

      GenericExceptionHandler(FailCodeType failCode, NestedHandler const& nestedHandler, Callable customAction = Callable(), bool supressExceptionsInAction = true):
         failCode_(failCode),
         nestedHandler(nestedHandler),
         customAction_(customAction),
         supressExceptionsInAction_(supressExceptionsInAction)
      {}

      FailCodeType handleException() { return handleException_(Bool2Type<std::is_same<ExceptionType, void>::value>()); }
      FailCodeType operator()() { return handleException(); }

   private:
      //////////////////////////////////////////////////////////////////////////
      // What follows is lots of code and compile-time trickery to work-around
      // partial support for template specialization in VS2010
      FailCodeType handleException_(Bool2Type<false> exceptionTypeNotVoid)
      {
         // Handle the case of ExceptionType != void
         // This means 'e' can and needs to be passed to the custom-action (if the exception is caught)
         try
         {
            return nestedHandler();
         }
         catch (ExceptionType& e)
         {
            // If the return type of the custom action is the same as FailCodeType (as opposed to void or even less plausible something else)
            // then return the result of custom action as the fail code.
            auto shouldReturnActionResult = Bool2Type< std::is_same< FailCodeType, decltype(customAction_(e)) >::value>();
            return handleNonVoidExceptionType(shouldReturnActionResult);
            e; // prevent unused variable warning. 'e' is used inside the decltype, but nowhere else (except here...)
         }
      }

      FailCodeType handleException_(Bool2Type<true> exceptionTypeIsVoid)
      {
         // Handle the case of ExceptionType == void: Interpret this as catch-all: '...'
         try
         {
            return nestedHandler();
         }
         catch (...)
         {
            // If the return type of the custom action is the same as FailCodeType (as opposed to void or even less plausible something else)
            // then return the result of custom action as the fail code.
            auto shouldReturnActionResult = Bool2Type< std::is_same< FailCodeType, decltype(customAction_()) >::value>();
            return handleVoidExceptionType(shouldReturnActionResult);
         }
      }

      FailCodeType handleVoidExceptionType(Bool2Type<true> shouldReturnFromCustomAction)
      {
         try { return customAction_(); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
         return failCode_;
      }

      FailCodeType handleVoidExceptionType(Bool2Type<false> shouldReturnFromCustomAction)
      {
         try { customAction_(); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
         return failCode_;
      }

      FailCodeType handleNonVoidExceptionType(Bool2Type<true> shouldReturnFromCustomAction)
      {
         try
         {
            try
            { throw; } // rethrow to get 'e' - can't pass it as argument since it may be of type void
            catch (ExceptionType& e)
            {
               // now we have 'e':
               try { return customAction_(e); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
               return failCode_;
            }
         } catch (...) {} // In case from some weird situation the re-thrown exception is not of type ExceptionType
         return failCode_;
      }

      FailCodeType handleNonVoidExceptionType(Bool2Type<false> shouldReturnFromCustomAction)
      {
         try
         {
            try
            { throw; } // rethrow to get 'e' - can't pass it as argument since it may be of type void
            catch (ExceptionType& e)
            {
               // now we have 'e':
               try { customAction_(e); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
               return failCode_;
            }
         } catch (...) {} // In case from some weird situation the re-thrown exception is not of type ExceptionType
         return failCode_;
      }

   private:
      FailCodeType failCode_;
      NestedHandler nestedHandler;
      Callable customAction_;
      bool supressExceptionsInAction_;
   };

   template <typename ExceptionType, typename Callable, typename NestedHandler>
   inline auto generic_handler(typename NestedHandler::FailCodeType failCode, Callable customAction, NestedHandler const& nestedHandler, bool supressExceptionsInAction = true)
   {  return GenericExceptionHandler<ExceptionType, NestedHandler, Callable>(failCode, nestedHandler, customAction, supressExceptionsInAction); }

   namespace
   {
      namespace detail
      {
         //////////////////////////////////////////////////////////////////////////
         // Helper functions for SFINAE overload resolution
         template< typename ... Ts >
         using void_t = void;

         template< typename T, typename = void >
         struct hasNestedFailCodeType : std::false_type {};

         template< typename T >
         struct hasNestedFailCodeType< T, void_t<typename T::FailCodeType> > : std::true_type {};
         //////////////////////////////////////////////////////////////////////////

         template <typename ExceptionType, typename Callable, typename FailCodeType>
         inline auto generic_handler_impl(FailCodeType failCode, Callable customAction, bool supressExceptionsInAction, std::false_type)
         {  return generic_handler<ExceptionType>(failCode, customAction, UnHandler<FailCodeType>(), supressExceptionsInAction);          }

         template <typename ExceptionType, typename NestedHandler, typename FailCodeType>
         inline auto generic_handler_impl(FailCodeType failCode, NestedHandler const& nestedHandler, bool supressExceptionsInAction, std::true_type)
         {  return generic_handler<ExceptionType>(failCode, DefaultNoAction<ExceptionType>(), nestedHandler, supressExceptionsInAction);  }
      }
   }

   template <typename ExceptionType, typename Callable, typename FailCodeType>
   inline auto generic_handler(FailCodeType code, Callable func, bool supressExceptionsInAction = true)
   {  return detail::generic_handler_impl<ExceptionType>(code, func, supressExceptionsInAction, detail::hasNestedFailCodeType<Callable>{}); }

   template <typename ExceptionType, typename FailCodeType>
   inline auto generic_handler(FailCodeType failCode)
   {  return generic_handler<ExceptionType>(failCode, DefaultNoAction<ExceptionType>(), UnHandler<FailCodeType>()); }
}
<commit_msg>Removed Bool2Type<> and use std::true_type/std::false_type instead.<commit_after>#pragma once

#include <iostream>
#include <type_traits> // for std::is_same<>
#include <functional>
#include <type_traits> // for std::false_type/std::true_type
#include <exception> // for std::is_same<>

namespace mittens
{
   //////////////////////////////////////////////////////////////////////////

   template <typename FailCodeType_ = int>
   class UnHandler
   {
   public:
      typedef FailCodeType_ FailCodeType;

      FailCodeType handleException()
      {
         // Instead of a call to `throw` we will check if the function was called inside a
         // catch clause. If so, `std::rethrow_exception(eptr)` is the same as `throw`.
         // Otherwise, throw an `std::logic_error` since this is obviously a bug.
         if (std::exception_ptr eptr = std::current_exception())
            std::rethrow_exception(eptr);

         throw std::logic_error("Mittens handler called outside of a catch clause! This is a BUG.");
      }
      FailCodeType operator()() { return handleException(); }
   };

   //////////////////////////////////////////////////////////////////////////

   // Helper default no-action type
   template <typename ExceptionType = void>
   struct DefaultNoAction
   {  void operator()(ExceptionType&){} };

   template <>
   struct DefaultNoAction<void>
   {  void operator()(){} };

   //////////////////////////////////////////////////////////////////////////

   template <typename ExceptionType, typename NestedHandler, typename Callable = DefaultNoAction<ExceptionType> >
   class GenericExceptionHandler
   {
   public:
      typedef typename NestedHandler::FailCodeType FailCodeType;

      GenericExceptionHandler(FailCodeType failCode, NestedHandler const& nestedHandler, Callable customAction = Callable(), bool supressExceptionsInAction = true):
         failCode_(failCode),
         nestedHandler(nestedHandler),
         customAction_(customAction),
         supressExceptionsInAction_(supressExceptionsInAction)
      {}

      FailCodeType handleException() { return handleException_(std::is_same<ExceptionType, void>::type{}); }
      FailCodeType operator()() { return handleException(); }

   private:
      //////////////////////////////////////////////////////////////////////////
      // What follows is lots of code and compile-time trickery to work-around
      // partial support for template specialization in VS2010
      FailCodeType handleException_(std::false_type exceptionTypeNotVoid)
      {
         // Handle the case of ExceptionType != void
         // This means 'e' can and needs to be passed to the custom-action (if the exception is caught)
         try
         {
            return nestedHandler();
         }
         catch (ExceptionType& e)
         {
            // If the return type of the custom action is the same as FailCodeType (as opposed to void or even less plausible something else)
            // then return the result of custom action as the fail code.
            auto shouldReturnActionResult = std::is_same< FailCodeType, decltype(customAction_(e)) >::type{};
            return handleNonVoidExceptionType(shouldReturnActionResult);
            e; // prevent unused variable warning. 'e' is used inside the decltype, but nowhere else (except here...)
         }
      }

      FailCodeType handleException_(std::true_type exceptionTypeIsVoid)
      {
         // Handle the case of ExceptionType == void: Interpret this as catch-all: '...'
         try
         {
            return nestedHandler();
         }
         catch (...)
         {
            // If the return type of the custom action is the same as FailCodeType (as opposed to void or even less plausible something else)
            // then return the result of custom action as the fail code.
            auto shouldReturnActionResult = std::is_same< FailCodeType, decltype(customAction_())>::type{};
            return handleVoidExceptionType(shouldReturnActionResult);
         }
      }

      FailCodeType handleVoidExceptionType(std::true_type shouldReturnFromCustomAction)
      {
         try { return customAction_(); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
         return failCode_;
      }

      FailCodeType handleVoidExceptionType(std::false_type shouldReturnFromCustomAction)
      {
         try { customAction_(); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
         return failCode_;
      }

      FailCodeType handleNonVoidExceptionType(std::true_type shouldReturnFromCustomAction)
      {
         try
         {
            try
            { throw; } // rethrow to get 'e' - can't pass it as argument since it may be of type void
            catch (ExceptionType& e)
            {
               // now we have 'e':
               try { return customAction_(e); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
               return failCode_;
            }
         } catch (...) {} // In case from some weird situation the re-thrown exception is not of type ExceptionType
         return failCode_;
      }

      FailCodeType handleNonVoidExceptionType(std::false_type shouldReturnFromCustomAction)
      {
         try
         {
            try
            { throw; } // rethrow to get 'e' - can't pass it as argument since it may be of type void
            catch (ExceptionType& e)
            {
               // now we have 'e':
               try { customAction_(e); } catch (...) { if (!supressExceptionsInAction_) throw; } // Run custom action. Force it no-throw by suppressing any exceptions or not.
               return failCode_;
            }
         } catch (...) {} // In case from some weird situation the re-thrown exception is not of type ExceptionType
         return failCode_;
      }

   private:
      FailCodeType failCode_;
      NestedHandler nestedHandler;
      Callable customAction_;
      bool supressExceptionsInAction_;
   };

   template <typename ExceptionType, typename Callable, typename NestedHandler>
   inline auto generic_handler(typename NestedHandler::FailCodeType failCode, Callable customAction, NestedHandler const& nestedHandler, bool supressExceptionsInAction = true)
   {  return GenericExceptionHandler<ExceptionType, NestedHandler, Callable>(failCode, nestedHandler, customAction, supressExceptionsInAction); }

   namespace
   {
      namespace detail
      {
         //////////////////////////////////////////////////////////////////////////
         // Helper functions for SFINAE overload resolution
         template< typename ... Ts >
         using void_t = void;

         template< typename T, typename = void >
         struct hasNestedFailCodeType : std::false_type {};

         template< typename T >
         struct hasNestedFailCodeType< T, void_t<typename T::FailCodeType> > : std::true_type {};
         //////////////////////////////////////////////////////////////////////////

         template <typename ExceptionType, typename Callable, typename FailCodeType>
         inline auto generic_handler_impl(FailCodeType failCode, Callable customAction, bool supressExceptionsInAction, std::false_type)
         {  return generic_handler<ExceptionType>(failCode, customAction, UnHandler<FailCodeType>(), supressExceptionsInAction);          }

         template <typename ExceptionType, typename NestedHandler, typename FailCodeType>
         inline auto generic_handler_impl(FailCodeType failCode, NestedHandler const& nestedHandler, bool supressExceptionsInAction, std::true_type)
         {  return generic_handler<ExceptionType>(failCode, DefaultNoAction<ExceptionType>(), nestedHandler, supressExceptionsInAction);  }
      }
   }

   template <typename ExceptionType, typename Callable, typename FailCodeType>
   inline auto generic_handler(FailCodeType code, Callable func, bool supressExceptionsInAction = true)
   {  return detail::generic_handler_impl<ExceptionType>(code, func, supressExceptionsInAction, detail::hasNestedFailCodeType<Callable>{}); }

   template <typename ExceptionType, typename FailCodeType>
   inline auto generic_handler(FailCodeType failCode)
   {  return generic_handler<ExceptionType>(failCode, DefaultNoAction<ExceptionType>(), UnHandler<FailCodeType>()); }
}
<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/thread.hpp"
#include "universe.hpp"
#include "blackhole/utils/noexcept.hpp"
#include "utils/noncopyable.hpp"
#include "utils/unique.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    log::exception_handler_t m_exception_handler;

    std::vector<std::unique_ptr<base_frontend_t>> m_frontends;

    log::attributes_t m_global_attributes;

    boost::thread_specific_ptr<scoped_attributes_concept_t> m_scoped_attributes;

    friend class scoped_attributes_concept_t;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enable();
    void disable();
    void set_filter(filter_t&& filter);
    void add_attribute(const log::attribute_pair_t& attribute);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    log::record_t open_record() const;
    log::record_t open_record(log::attribute_pair_t local_attribute) const;
    log::record_t open_record(log::attributes_t local_attributes) const;

    void push(log::record_t&& record) const;

private:
    log::attributes_t get_event_attributes() const;
    log::attributes_t get_thread_attributes() const;
};

// NOTE: It's not movable to avoid moving to another thread.
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    ~scoped_attributes_concept_t();

    virtual const log::attributes_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

private:
    Level level;

public:
    verbose_logger_t() :
        logger_base_t(),
        level(static_cast<level_type>(0))
    {}

    //! @compat GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(0))
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    //!@todo: Docs.
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
    }

    log::record_t open_record(level_type level) const {
        typedef typename aux::underlying_type<level_type>::type underlying_type;
        if (static_cast<underlying_type>(level) < static_cast<underlying_type>(this->level)) {
            return log::record_t();
        }

        log::attributes_t attributes = { keyword::severity<Level>() = level };
        return logger_base_t::open_record(std::move(attributes));
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/implementation/logger.ipp"
#endif
<commit_msg>[Bug Fix] Scoped attribute's destructor is now virtual.<commit_after>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/thread.hpp"
#include "universe.hpp"
#include "blackhole/utils/noexcept.hpp"
#include "utils/noncopyable.hpp"
#include "utils/unique.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    log::exception_handler_t m_exception_handler;

    std::vector<std::unique_ptr<base_frontend_t>> m_frontends;

    log::attributes_t m_global_attributes;

    boost::thread_specific_ptr<scoped_attributes_concept_t> m_scoped_attributes;

    friend class scoped_attributes_concept_t;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enable();
    void disable();
    void set_filter(filter_t&& filter);
    void add_attribute(const log::attribute_pair_t& attribute);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    log::record_t open_record() const;
    log::record_t open_record(log::attribute_pair_t local_attribute) const;
    log::record_t open_record(log::attributes_t local_attributes) const;

    void push(log::record_t&& record) const;

private:
    log::attributes_t get_event_attributes() const;
    log::attributes_t get_thread_attributes() const;
};

// NOTE: It's not movable to avoid moving to another thread.
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const log::attributes_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

private:
    Level level;

public:
    verbose_logger_t() :
        logger_base_t(),
        level(static_cast<level_type>(0))
    {}

    //! @compat GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(0))
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    //!@todo: Docs.
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
    }

    log::record_t open_record(level_type level) const {
        typedef typename aux::underlying_type<level_type>::type underlying_type;
        if (static_cast<underlying_type>(level) < static_cast<underlying_type>(this->level)) {
            return log::record_t();
        }

        log::attributes_t attributes = { keyword::severity<Level>() = level };
        return logger_base_t::open_record(std::move(attributes));
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/implementation/logger.ipp"
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: validat.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-03 15:46:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    sal_uInt32          nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    using ScConditionEntry::operator==;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                BOOL bCompileEnglish = FALSE, BOOL bCompileXML = FALSE );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
    virtual ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress& rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    sal_uInt32      GetKey() const          { return nKey; }
    void            SetKey(sal_uInt32 nNew) { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only if it is non-NULL,
        @param pStrings  (out-param) Optionally NULL, string list to fill with list validation entires.
        @param pCell     can be NULL if it is not necessary to which element in the list is selected.
        @param rPos      the base address for relative references.
        @param rTokArr   Formula token array.
        @param rMatch    (out-param) the index of the first item that matched, -1 if nothing matched.
        @return  true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */
    bool            GetSelectionFromFormula( TypedStrCollection* pStrings,
                                             ScBaseCell* pCell, const ScAddress& rPos,
                                             const ScTokenArray& rTokArr, int& rMatch ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW)

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( sal_uInt32 nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<commit_msg>INTEGRATION: CWS odff (1.13.64); FILE MERGED 2007/09/06 10:43:07 er 1.13.64.1: #i81063# new ScGrammar; get rid of SetCompileEnglish, SetCompileXML, GetEnglishFormula, ...<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: validat.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 15:22:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    sal_uInt32          nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    using ScConditionEntry::operator==;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                const ScGrammar::Grammar eGrammar = ScGrammar::GRAM_DEFAULT );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
    virtual ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress& rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    sal_uInt32      GetKey() const          { return nKey; }
    void            SetKey(sal_uInt32 nNew) { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only if it is non-NULL,
        @param pStrings  (out-param) Optionally NULL, string list to fill with list validation entires.
        @param pCell     can be NULL if it is not necessary to which element in the list is selected.
        @param rPos      the base address for relative references.
        @param rTokArr   Formula token array.
        @param rMatch    (out-param) the index of the first item that matched, -1 if nothing matched.
        @return  true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */
    bool            GetSelectionFromFormula( TypedStrCollection* pStrings,
                                             ScBaseCell* pCell, const ScAddress& rPos,
                                             const ScTokenArray& rTokArr, int& rMatch ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW)

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( sal_uInt32 nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: validat.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-19 07:47:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    ULONG               nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                BOOL bCompileEnglish = FALSE, BOOL bCompileXML = FALSE );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
            ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    ULONG           GetKey() const          { return nKey; }
    void            SetKey(ULONG nNew)      { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to get a cell range from a list validation formula.
        @descr  The formula may contain a cell reference, a defined name or a database range.
        @param rRange  (out-param) The resulting cell range.
        @param rBaseAddr  Base address for relative references.
        @return  true = Cell range found, rRange is valid. */
    bool            GetRangeFromFormula( ScRange& rRange, const ScAddress& rBaseAddr, ScTokenArray& rTokArr, int nRecCount = 0 ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW);

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( ULONG nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, short nDx, short nDy, short nDz );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<commit_msg>INTEGRATION: CWS rowlimit (1.5.74); FILE MERGED 2004/01/12 17:15:10 er 1.5.74.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short<commit_after>/*************************************************************************
 *
 *  $RCSfile: validat.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-04 10:17:59 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    ULONG               nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                BOOL bCompileEnglish = FALSE, BOOL bCompileXML = FALSE );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
            ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    ULONG           GetKey() const          { return nKey; }
    void            SetKey(ULONG nNew)      { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to get a cell range from a list validation formula.
        @descr  The formula may contain a cell reference, a defined name or a database range.
        @param rRange  (out-param) The resulting cell range.
        @param rBaseAddr  Base address for relative references.
        @return  true = Cell range found, rRange is valid. */
    bool            GetRangeFromFormula( ScRange& rRange, const ScAddress& rBaseAddr, ScTokenArray& rTokArr, int nRecCount = 0 ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW);

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( ULONG nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_UTIL_SPATIAL_INDEX_HPP
#define MAPNIK_UTIL_SPATIAL_INDEX_HPP

//mapnik
#include <mapnik/coord.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/query.hpp>
#include <mapnik/geom_util.hpp>
// stl
#include <type_traits>

using mapnik::box2d;
using mapnik::query;

namespace mapnik { namespace util {

template <typename Value, typename Filter, typename InputStream>
class spatial_index
{
public:
    static void query(Filter const& filter, InputStream& in,std::vector<Value>& pos);
    static box2d<double> bounding_box( InputStream& in );
private:

    spatial_index();
    ~spatial_index();
    spatial_index(spatial_index const&);
    spatial_index& operator=(spatial_index const&);
    static int read_ndr_integer(InputStream& in);
    static void read_envelope(InputStream& in, box2d<double>& envelope);
    static void query_node(Filter const& filter, InputStream& in, std::vector<Value> & results);
};

template <typename Value, typename Filter, typename InputStream>
box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStream& in)
{
    static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
    in.seekg(16 + 4, std::ios::beg);
    box2d<double> box;
    read_envelope(in, box);
    in.seekg(0, std::ios::beg);
    return box;
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
    static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout types");
    in.seekg(16, std::ios::beg);
    query_node(filter, in, results);
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query_node(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
    int offset = read_ndr_integer(in);
    box2d<double> node_ext;
    read_envelope(in, node_ext);
    int num_shapes = read_ndr_integer(in);
    if (!filter.pass(node_ext))
    {
        in.seekg(offset + num_shapes * sizeof(Value) + 4, std::ios::cur);
        return;
    }

    for (int i = 0; i < num_shapes; ++i)
    {
        Value item;
        in.read(reinterpret_cast<char*>(&item), sizeof(Value));
        results.push_back(std::move(item));
    }

    int children = read_ndr_integer(in);
    for (int j = 0; j < children; ++j)
    {
        query_node(filter, in, results);
    }
}

template <typename Value, typename Filter, typename InputStream>
int spatial_index<Value, Filter, InputStream>::read_ndr_integer(InputStream& in)
{
    char b[4];
    in.read(b, 4);
    return (b[0] & 0xff) | (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::read_envelope(InputStream& in, box2d<double>& envelope)
{
    in.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
}

}} // mapnik/util

#endif // MAPNIK_UTIL_SPATIAL_INDEX_HPP
<commit_msg>spatial_index - implement `query_first_n'<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_UTIL_SPATIAL_INDEX_HPP
#define MAPNIK_UTIL_SPATIAL_INDEX_HPP

//mapnik
#include <mapnik/coord.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/query.hpp>
#include <mapnik/geom_util.hpp>
// stl
#include <type_traits>

using mapnik::box2d;
using mapnik::query;

namespace mapnik { namespace util {

template <typename Value, typename Filter, typename InputStream>
class spatial_index
{
public:
    static void query(Filter const& filter, InputStream& in,std::vector<Value>& pos);
    static box2d<double> bounding_box( InputStream& in );
    static void query_first_n(Filter const& filter, InputStream & in, std::vector<Value>& pos, std::size_t count);
private:

    spatial_index();
    ~spatial_index();
    spatial_index(spatial_index const&);
    spatial_index& operator=(spatial_index const&);
    static int read_ndr_integer(InputStream& in);
    static void read_envelope(InputStream& in, box2d<double>& envelope);
    static void query_node(Filter const& filter, InputStream& in, std::vector<Value> & results);
    static void query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value> & results, std::size_t count);
};

template <typename Value, typename Filter, typename InputStream>
box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStream& in)
{
    static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
    in.seekg(16 + 4, std::ios::beg);
    box2d<double> box;
    read_envelope(in, box);
    in.seekg(0, std::ios::beg);
    return box;
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
    static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout types");
    in.seekg(16, std::ios::beg);
    query_node(filter, in, results);
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query_node(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
    int offset = read_ndr_integer(in);
    box2d<double> node_ext;
    read_envelope(in, node_ext);
    int num_shapes = read_ndr_integer(in);
    if (!filter.pass(node_ext))
    {
        in.seekg(offset + num_shapes * sizeof(Value) + 4, std::ios::cur);
        return;
    }

    for (int i = 0; i < num_shapes; ++i)
    {
        Value item;
        in.read(reinterpret_cast<char*>(&item), sizeof(Value));
        results.push_back(std::move(item));
    }

    int children = read_ndr_integer(in);
    for (int j = 0; j < children; ++j)
    {
        query_node(filter, in, results);
    }
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query_first_n(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
{
    static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout types");
    in.seekg(16, std::ios::beg);
    query_first_n_impl(filter, in, results, count);
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
{
    if (results.size() == count) return;
    int offset = read_ndr_integer(in);
    box2d<double> node_ext;
    read_envelope(in, node_ext);
    int num_shapes = read_ndr_integer(in);
    if (!filter.pass(node_ext))
    {
        in.seekg(offset + num_shapes * sizeof(Value) + 4, std::ios::cur);
        return;
    }

    for (int i = 0; i < num_shapes; ++i)
    {
        Value item;
        in.read(reinterpret_cast<char*>(&item), sizeof(Value));
        if (results.size() < count) results.push_back(std::move(item));
    }
    int children = read_ndr_integer(in);
    for (int j = 0; j < children; ++j)
    {
        query_first_n_impl(filter, in, results, count);
    }
}

template <typename Value, typename Filter, typename InputStream>
int spatial_index<Value, Filter, InputStream>::read_ndr_integer(InputStream& in)
{
    char b[4];
    in.read(b, 4);
    return (b[0] & 0xff) | (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
}

template <typename Value, typename Filter, typename InputStream>
void spatial_index<Value, Filter, InputStream>::read_envelope(InputStream& in, box2d<double>& envelope)
{
    in.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
}

}} // mapnik/util

#endif // MAPNIK_UTIL_SPATIAL_INDEX_HPP
<|endoftext|>


<commit_before>#pragma once
#include <memory>
#include <functional>

namespace th
{
template<typename BaseType>
class CopyablePolymorphic
{
    public:
    template<typename DerivedType>
    CopyablePolymorphic(const DerivedType& need)
    {
        static_assert(std::is_base_of<BaseType, DerivedType>::value, "Can only be constructed from types that inherit BaseType");

        mCopyFunction = [] (const std::unique_ptr<BaseType>& needToCopy)
        {
            const auto originalPtr = static_cast<DerivedType*>(needToCopy.get());
            return std::unique_ptr<BaseType>(new DerivedType(*originalPtr)); //uses the normal copy mechanics of the DerivedType class
        };

        mValue.reset(new DerivedType(need));
    }

    CopyablePolymorphic(const CopyablePolymorphic& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
    }

    CopyablePolymorphic(CopyablePolymorphic&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
    }

    CopyablePolymorphic& operator=(const CopyablePolymorphic& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
        return *this;
    }

    CopyablePolymorphic& operator=(CopyablePolymorphic&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
        return *this;
    }

    const BaseType& operator*() const
    {
        return *mValue;
    }

    BaseType& operator*()
    {
        return *mValue;
    }

    const BaseType* operator->() const
    {
        return mValue.get();
    }

    BaseType* operator->()
    {
        return mValue.get();
    }

    private:
    std::function<std::unique_ptr<BaseType>(const std::unique_ptr<BaseType>&)> mCopyFunction;
    std::unique_ptr<BaseType> mValue;
};
}
<commit_msg>Renamed variable from 'need' to 'derived'<commit_after>#pragma once
#include <memory>
#include <functional>

namespace th
{
template<typename BaseType>
class CopyablePolymorphic
{
    public:
    template<typename DerivedType>
    CopyablePolymorphic(const DerivedType& derived)
    {
        static_assert(std::is_base_of<BaseType, DerivedType>::value, "Can only be constructed from types that inherit BaseType");

        mCopyFunction = [] (const std::unique_ptr<BaseType>& derivedToCopy)
        {
            const auto originalPtr = static_cast<DerivedType*>(derivedToCopy.get());
            return std::unique_ptr<BaseType>(new DerivedType(*originalPtr)); //uses the normal copy mechanics of the DerivedType class
        };

        mValue.reset(new DerivedType(derived));
    }

    CopyablePolymorphic(const CopyablePolymorphic& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
    }

    CopyablePolymorphic(CopyablePolymorphic&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
    }

    CopyablePolymorphic& operator=(const CopyablePolymorphic& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
        return *this;
    }

    CopyablePolymorphic& operator=(CopyablePolymorphic&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
        return *this;
    }

    const BaseType& operator*() const
    {
        return *mValue;
    }

    BaseType& operator*()
    {
        return *mValue;
    }

    const BaseType* operator->() const
    {
        return mValue.get();
    }

    BaseType* operator->()
    {
        return mValue.get();
    }

    private:
    std::function<std::unique_ptr<BaseType>(const std::unique_ptr<BaseType>&)> mCopyFunction;
    std::unique_ptr<BaseType> mValue;
};
}
<|endoftext|>


<commit_before>#include <ctime>
#include <cstdio>
#include <cstring>
#include <But/assert.hpp>
#include <But/Log/Field/UtcIsoDateTime.hpp>

using std::to_string;

namespace But
{
namespace Log
{
namespace Field
{

namespace
{
auto convert(time_t timestamp)
{
  struct tm out;
  if( not gmtime_r(&timestamp, &out) )
    BUT_THROW( ConversionError, strerror(errno) );
  return out;
}
}

std::string UtcIsoDateTime::date() const
{
  const auto tmp = convert(timestamp_);
  char out[1+2 + 1+2 + 1];
  BUT_ASSERT( tmp.tm_mon+1 <= 12 );
  BUT_ASSERT( tmp.tm_mday  <= 31 );
  sprintf(out, "-%02d-%02d", 1+tmp.tm_mon, tmp.tm_mday);
  return to_string(1900+tmp.tm_year) + out;
}

std::string UtcIsoDateTime::time() const
{
  const auto tmp = convert(timestamp_);
  char out[2+1 + 2+1 + 2 + 1];
  BUT_ASSERT( tmp.tm_hour < 24 );
  BUT_ASSERT( tmp.tm_min  < 60 );
  BUT_ASSERT( tmp.tm_sec  < 60 );
  sprintf(out, "%02d:%02d:%02d", tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
  return out;
}

}
}
}
<commit_msg>workaround to fix GCC's 8.x warning<commit_after>#include <ctime>
#include <cstdio>
#include <cstring>
#include <But/assert.hpp>
#include <But/Log/Field/UtcIsoDateTime.hpp>

using std::to_string;

namespace But
{
namespace Log
{
namespace Field
{

namespace
{
auto convert(time_t timestamp)
{
  struct tm out;
  if( not gmtime_r(&timestamp, &out) )
    BUT_THROW( ConversionError, strerror(errno) );
  return out;
}
}

std::string UtcIsoDateTime::date() const
{
  const auto tmp = convert(timestamp_);
  char out[64];     // kept big, to silence GCC's 8 warning...
  BUT_ASSERT( tmp.tm_mon+1 <= 12 );
  BUT_ASSERT( tmp.tm_mday  <= 31 );
  sprintf(out, "-%02d-%02d", 1+tmp.tm_mon, tmp.tm_mday);
  return to_string(1900+tmp.tm_year) + out;
}

std::string UtcIsoDateTime::time() const
{
  const auto tmp = convert(timestamp_);
  char out[64];     // kept big, to silence GCC's 8 warning...
  BUT_ASSERT( tmp.tm_hour < 24 );
  BUT_ASSERT( tmp.tm_min  < 60 );
  BUT_ASSERT( tmp.tm_sec  < 60 );
  sprintf(out, "%02d:%02d:%02d", tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
  return out;
}

}
}
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/value_fwd.hpp"
#include "etl/temporary.hpp"
#include "etl/config.hpp"
#include "etl/traits_lite.hpp"

#ifdef ETL_MKL_MODE
#include "mkl_trans.h"
#endif

/**
 * Implementations of matrix transposition.
 *    1. Simple implementation using for loop
 *    2. Implementations using MKL
 *
 * Square and rectangular implementation are separated.
 */

namespace etl {

namespace detail {

template<typename C, typename Enable = void>
struct inplace_square_transpose {
    template<typename CC>
    static void apply(CC&& c){
        using std::swap;

        const auto N = etl::dim<0>(c);

        for(std::size_t i = 0; i < N - 1; ++i){
            for(std::size_t j = i + 1; j < N; ++j){
                swap(c(i, j), c(j, i));
            }
        }
    }
};

template<typename C, typename Enable = void>
struct inplace_rectangular_transpose {
    template<typename CC>
    static void apply(CC&& mat){
        auto copy = force_temporary(mat);

        auto data = mat.memory_start();

        //Dimensions prior to transposition
        const auto N = etl::dim<0>(mat);
        const auto M = etl::dim<1>(mat);

        for(std::size_t i = 0; i < N; ++i){
            for(std::size_t j = 0; j < M; ++j){
                data[j * N + i] = copy(i, j);
            }
        }
    }

    //This implementation is really slow but has O(1) space
    template<typename CC>
    static void real_inplace(CC&& mat){
        using std::swap;

        const auto N = etl::dim<0>(mat);
        const auto M = etl::dim<1>(mat);

        auto data = mat.memory_start();

        for(std::size_t k = 0; k < N*M; k++) {
            auto idx = k;
            do {
                idx = (idx % N) * M + (idx / N);
            } while(idx < k);
            std::swap(data[k], data[idx]);
        }
    }
};

#ifdef ETL_MKL_MODE

template<typename C>
struct inplace_square_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_single_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        mkl_simatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0f, c.memory_start(), etl::dim<1>(c), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_square_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_double_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        mkl_dimatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, c.memory_start(), etl::dim<1>(c), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_rectangular_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_single_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        auto copy = force_temporary(c);
        mkl_somatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, copy.memory_start(), etl::dim<1>(c), c.memory_start(), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_rectangular_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_double_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        auto copy = force_temporary(c);
        mkl_domatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, copy.memory_start(), etl::dim<1>(c), c.memory_start(), etl::dim<0>(c));
    }
};

#endif

} //end of namespace detail

} //end of namespace etl
<commit_msg>Update doc<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/value_fwd.hpp"
#include "etl/temporary.hpp"
#include "etl/config.hpp"
#include "etl/traits_lite.hpp"

#ifdef ETL_MKL_MODE
#include "mkl_trans.h"
#endif

/**
 * Implementations of inplace matrix transposition.
 *    1. Simple implementation using for loop
 *    2. Implementations using MKL
 *
 * Square and rectangular implementation are separated.
 */

namespace etl {

namespace detail {

template<typename C, typename Enable = void>
struct inplace_square_transpose {
    template<typename CC>
    static void apply(CC&& c){
        using std::swap;

        const auto N = etl::dim<0>(c);

        for(std::size_t i = 0; i < N - 1; ++i){
            for(std::size_t j = i + 1; j < N; ++j){
                swap(c(i, j), c(j, i));
            }
        }
    }
};

template<typename C, typename Enable = void>
struct inplace_rectangular_transpose {
    template<typename CC>
    static void apply(CC&& mat){
        auto copy = force_temporary(mat);

        auto data = mat.memory_start();

        //Dimensions prior to transposition
        const auto N = etl::dim<0>(mat);
        const auto M = etl::dim<1>(mat);

        for(std::size_t i = 0; i < N; ++i){
            for(std::size_t j = 0; j < M; ++j){
                data[j * N + i] = copy(i, j);
            }
        }
    }

    //This implementation is really slow but has O(1) space
    template<typename CC>
    static void real_inplace(CC&& mat){
        using std::swap;

        const auto N = etl::dim<0>(mat);
        const auto M = etl::dim<1>(mat);

        auto data = mat.memory_start();

        for(std::size_t k = 0; k < N*M; k++) {
            auto idx = k;
            do {
                idx = (idx % N) * M + (idx / N);
            } while(idx < k);
            std::swap(data[k], data[idx]);
        }
    }
};

#ifdef ETL_MKL_MODE

template<typename C>
struct inplace_square_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_single_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        mkl_simatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0f, c.memory_start(), etl::dim<1>(c), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_square_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_double_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        mkl_dimatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, c.memory_start(), etl::dim<1>(c), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_rectangular_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_single_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        auto copy = force_temporary(c);
        mkl_somatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, copy.memory_start(), etl::dim<1>(c), c.memory_start(), etl::dim<0>(c));
    }
};

template<typename C>
struct inplace_rectangular_transpose<C, std::enable_if_t<has_direct_access<C>::value && is_double_precision<C>::value>> {
    template<typename CC>
    static void apply(CC&& c){
        auto copy = force_temporary(c);
        mkl_domatcopy('R', 'T', etl::dim<0>(c), etl::dim<1>(c), 1.0, copy.memory_start(), etl::dim<1>(c), c.memory_start(), etl::dim<0>(c));
    }
};

#endif

} //end of namespace detail

} //end of namespace etl
<|endoftext|>