<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: porrst.hxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:02:07 $
 *
 *  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 _PORRST_HXX
#define _PORRST_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

#include "porlay.hxx"
#include "porexp.hxx"

#ifdef VERTICAL_LAYOUT
#define LINE_BREAK_WIDTH        150
#define SPECIAL_FONT_HEIGHT     200
#endif

class SwTxtFormatInfo;

/*************************************************************************
 *                      class SwTmpEndPortion
 *************************************************************************/

class SwTmpEndPortion : public SwLinePortion
{
public:
            SwTmpEndPortion( const SwLinePortion &rPortion );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwBreakPortion
 *************************************************************************/

class SwBreakPortion : public SwLinePortion
{
public:
            SwBreakPortion( const SwLinePortion &rPortion );
    // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind.
    virtual SwLinePortion *Compress();
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;

    // Accessibility: pass information about this portion to the PortionHandler
    virtual void HandlePortion( SwPortionHandler& rPH ) const;

    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwKernPortion
 *************************************************************************/

class SwKernPortion : public SwLinePortion
{
    short nKern;
    sal_Bool bBackground;

#ifdef VERTICAL_LAYOUT
    sal_Bool bGridKern;
#endif

public:

#ifdef VERTICAL_LAYOUT
    // This constructor automatically appends the portion to rPortion
    // bBG indicates, that the background of the kerning portion has to
    // be painted, e.g., if the portion if positioned between to fields.
    // bGridKern indicates, that the kerning portion is used to provide
    // additional space in grid mode.
    SwKernPortion( SwLinePortion &rPortion, short nKrn,
                   sal_Bool bBG = sal_False, sal_Bool bGridKern = sal_False );

    // This constructor only sets the height and ascent to the values
    // of rPortion. It is only used for kerning portions for grid mode
    SwKernPortion( const SwLinePortion &rPortion );
#else
    SwKernPortion( SwLinePortion &rPortion, short nKrn,
                   sal_Bool bBG = sal_False );
#endif

    virtual void FormatEOL( SwTxtFormatInfo &rInf );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;

    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwArrowPortion
 *************************************************************************/

class SwArrowPortion : public SwLinePortion
{
    Point aPos;
    sal_Bool bLeft;
public:
            SwArrowPortion( const SwLinePortion &rPortion );
            SwArrowPortion( const SwTxtPaintInfo &rInf );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual SwLinePortion *Compress();
    inline sal_Bool IsLeft() const { return bLeft; }
    inline const Point& GetPos() const { return aPos; }
    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwHangingPortion
 * The characters which are forbidden at the start of a line like the dot and
 * other punctuation marks are allowed to display in the margin of the page
 * by a user option.
 * The SwHangingPortion is the corresponding textportion to do that.
 *************************************************************************/

class SwHangingPortion : public SwTxtPortion
{
    KSHORT nInnerWidth;
public:
    inline SwHangingPortion( SwPosSize aSize ) : nInnerWidth( aSize.Width() )
        { SetWhichPor( POR_HNG );  SetLen( 1 ); Height( aSize.Height() ); }

    inline KSHORT GetInnerWidth() const { return nInnerWidth; }
};

/*************************************************************************
 *                      class SwHiddenTextPortion
 * Is used to hide text
 *************************************************************************/

class SwHiddenTextPortion : public SwLinePortion
{
public:
    inline SwHiddenTextPortion( xub_StrLen nLen )
        { SetWhichPor( POR_HIDDEN_TXT );  SetLen( nLen ); }

    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
};

/*************************************************************************
 *                  inline - Implementations
 *************************************************************************/

CLASSIO( SwBreakPortion )
CLASSIO( SwEndPortion )
CLASSIO( SwKernPortion )
CLASSIO( SwArrowPortion )

#endif
<commit_msg>INTEGRATION: CWS thaiissues (1.16.34); FILE MERGED 2005/10/25 06:46:21 fme 1.16.34.1: #i55716# Feature - Control characters<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: porrst.hxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: obo $ $Date: 2005-11-16 09:31:27 $
 *
 *  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 _PORRST_HXX
#define _PORRST_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

#include "porlay.hxx"
#include "porexp.hxx"

#ifdef VERTICAL_LAYOUT
#define LINE_BREAK_WIDTH        150
#define SPECIAL_FONT_HEIGHT     200
#endif

class SwTxtFormatInfo;

/*************************************************************************
 *                      class SwTmpEndPortion
 *************************************************************************/

class SwTmpEndPortion : public SwLinePortion
{
public:
            SwTmpEndPortion( const SwLinePortion &rPortion );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwBreakPortion
 *************************************************************************/

class SwBreakPortion : public SwLinePortion
{
public:
            SwBreakPortion( const SwLinePortion &rPortion );
    // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind.
    virtual SwLinePortion *Compress();
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;

    // Accessibility: pass information about this portion to the PortionHandler
    virtual void HandlePortion( SwPortionHandler& rPH ) const;

    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwKernPortion
 *************************************************************************/

class SwKernPortion : public SwLinePortion
{
    short nKern;
    sal_Bool bBackground;

#ifdef VERTICAL_LAYOUT
    sal_Bool bGridKern;
#endif

public:

#ifdef VERTICAL_LAYOUT
    // This constructor automatically appends the portion to rPortion
    // bBG indicates, that the background of the kerning portion has to
    // be painted, e.g., if the portion if positioned between to fields.
    // bGridKern indicates, that the kerning portion is used to provide
    // additional space in grid mode.
    SwKernPortion( SwLinePortion &rPortion, short nKrn,
                   sal_Bool bBG = sal_False, sal_Bool bGridKern = sal_False );

    // This constructor only sets the height and ascent to the values
    // of rPortion. It is only used for kerning portions for grid mode
    SwKernPortion( const SwLinePortion &rPortion );
#else
    SwKernPortion( SwLinePortion &rPortion, short nKrn,
                   sal_Bool bBG = sal_False );
#endif

    virtual void FormatEOL( SwTxtFormatInfo &rInf );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;

    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwArrowPortion
 *************************************************************************/

class SwArrowPortion : public SwLinePortion
{
    Point aPos;
    sal_Bool bLeft;
public:
            SwArrowPortion( const SwLinePortion &rPortion );
            SwArrowPortion( const SwTxtPaintInfo &rInf );
    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual SwLinePortion *Compress();
    inline sal_Bool IsLeft() const { return bLeft; }
    inline const Point& GetPos() const { return aPos; }
    OUTPUT_OPERATOR
};

/*************************************************************************
 *                      class SwHangingPortion
 * The characters which are forbidden at the start of a line like the dot and
 * other punctuation marks are allowed to display in the margin of the page
 * by a user option.
 * The SwHangingPortion is the corresponding textportion to do that.
 *************************************************************************/

class SwHangingPortion : public SwTxtPortion
{
    KSHORT nInnerWidth;
public:
    inline SwHangingPortion( SwPosSize aSize ) : nInnerWidth( aSize.Width() )
        { SetWhichPor( POR_HNG );  SetLen( 1 ); Height( aSize.Height() ); }

    inline KSHORT GetInnerWidth() const { return nInnerWidth; }
};

/*************************************************************************
 *                      class SwHiddenTextPortion
 * Is used to hide text
 *************************************************************************/

class SwHiddenTextPortion : public SwLinePortion
{
public:
    inline SwHiddenTextPortion( xub_StrLen nLen )
        { SetWhichPor( POR_HIDDEN_TXT );  SetLen( nLen ); }

    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
};

/*************************************************************************
 *                      class SwControlCharPortion
 *************************************************************************/

class SwControlCharPortion : public SwLinePortion
{

private:
    mutable USHORT mnViewWidth;            // used to cache a calculated value
    mutable USHORT mnHalfCharWidth;        // used to cache a calculated value
    sal_Unicode mcChar;

public:

    inline SwControlCharPortion( sal_Unicode cChar )
        : mnViewWidth( 0 ), mnHalfCharWidth( 0 ), mcChar( cChar )
    {
        SetWhichPor( POR_CONTROLCHAR ); SetLen( 1 );
    }

    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
    virtual KSHORT GetViewWidth( const SwTxtSizeInfo& rInf ) const;
};

/*************************************************************************
 *                  inline - Implementations
 *************************************************************************/

CLASSIO( SwBreakPortion )
CLASSIO( SwEndPortion )
CLASSIO( SwKernPortion )
CLASSIO( SwArrowPortion )

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkNullCanvas.h"

#include "SkCanvas.h"
#include "SKNWayCanvas.h"

SkCanvas* SkCreateNullCanvas() {
    // An N-Way canvas forwards calls to N canvas's. When N == 0 it's
    // effectively a null canvas.
    return SkNEW(SkNWayCanvas(0,0));
}
<commit_msg>fix SkNWayCanvas cons call again.<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkNullCanvas.h"

#include "SkCanvas.h"
#include "SKNWayCanvas.h"

SkCanvas* SkCreateNullCanvas() {
    // An N-Way canvas forwards calls to N canvas's. When N == 0 it's
    // effectively a null canvas.
    return SkNEW_ARGS(SkNWayCanvas, (0,0));
}
<|endoftext|>


<commit_before>#ifndef __JSON_HPP__
#define __JSON_HPP__

#include <cctype>
#include <string>
#include <vector>
#include <array>
#include <regex>

namespace JSON {
	using namespace std;

	struct Error {};
	struct SyntaxError : public Error {};
	struct LoadError : public Error {};
	struct AccessError : public Error {};

	template<typename _Value, char const ..._szName>
	struct Field {
		static char const s_szName;
		typedef _Value Type;
	};

	template<char const ..._sz>
	struct FieldName {};

	template<typename _Name, typename ..._Fields>
	struct FieldType {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct FieldType<FieldName<_szName...>, Field<_Value, _szName...>, _OtherFields...> {
		typedef _Value Type;
	};

	template<char const ..._szFieldName, typename _FirstField, typename ..._OtherFields>
	struct FieldType<FieldName<_szFieldName...>, _FirstField, _OtherFields...> {
		typedef typename FieldType<FieldName<_szFieldName...>, _OtherFields...>::Type Type;
	};

	template<typename _Value, char const ..._szName>
	char const Field<_Value, _szName...>::s_szName = { _szName... };

	template<typename ..._Fields>
	struct Object {};

	template<typename _Field, typename ..._Fields>
	struct Getter {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, Field<_Value, _szName...>, _OtherFields...> {
		inline static _Value &Get(Object<Field<_Value, _szName...>, _OtherFields...> &rObject) {
			return rObject.m_Value;
		}

		inline static _Value const &Get(Object<Field<_Value, _szName...>, _OtherFields...> const &rObject) {
			return rObject.m_Value;
		}
	};

	template<typename _Value, char const ..._szName, typename _FirstField, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...> {
		inline static _Value &Get(Object<_FirstField, _OtherFields...> &rObject) {
			return Getter<Field<_Value, _szName...>, _OtherFields...>::Get(rObject);
		}

		inline static _Value const &Get(Object<_FirstField, _OtherFields...> const &rObject) {
			return Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...>::Get(rObject);
		}
	};

	template<>
	struct Object<> {
		Object() {}
		virtual ~Object() {}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Object<Field<_Value, _szName...>, _OtherFields...> :
		public Object<_OtherFields...>
	{
		static char const s_szName[];
		_Value m_Value;

		Object() {}

		virtual ~Object() {}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type &Get() {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type const &Get() const {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	char const Object<Field<_Value, _szName...>, _OtherFields...>::s_szName[] = { _szName... };

	template<typename _Type>
	struct Serializer {
		static _Type Load(istream &ris);
		static ostream &Store(ostream &ros, _Type const &r);
	};

	template<>
	struct Serializer<nullptr_t> {
		static nullptr_t Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, nullptr_t const &r) {
			return ros << "null";
		}
	};

	template<>
	struct Serializer<bool> {
		static bool Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, bool const &r) {
			if (r) {
				return ros << "true";
			} else {
				return ros << "false";
			}
		}
	};

	template<>
	struct Serializer<int> {
		static int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<unsigned int> {
		static unsigned int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, unsigned int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<double> {
		static double Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, double const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<string> {
		static string Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, string const &r) {
			return ros << '\"' << r << '\"'; // FIXME escape special characters
		}
	};

	template<typename ..._Fields>
	struct Serializer<Object<_Fields...>> {
		static Object<_Fields...> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element>
	struct Serializer<vector<_Element>> {
		static vector<_Element> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element, unsigned int _c>
	struct Serializer<array<_Element, _c>> {
		static array<_Element, _c> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Type>
	inline _Type Load(istream &ris) {
		return Serializer<_Type>::Load(ris);
	}

	template<typename _Type>
	inline ostream &Store(ostream &ros, _Type const &r) {
		return Serializer<_Type>::Store(ros, r);
	}
}

#define UNPACK(sz) (sz)[0], ((sz)[0] > 0) ? UNPACK((sz) + 1) : 0

#endif
<commit_msg>I/O shift operators<commit_after>#ifndef __JSON_HPP__
#define __JSON_HPP__

#include <cctype>
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <regex>

namespace JSON {
	using namespace std;

	struct Error {};
	struct SyntaxError : public Error {};
	struct LoadError : public Error {};
	struct AccessError : public Error {};

	template<typename _Value, char const ..._szName>
	struct Field {
		static char const s_szName;
		typedef _Value Type;
	};

	template<char const ..._sz>
	struct FieldName {};

	template<typename _Name, typename ..._Fields>
	struct FieldType {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct FieldType<FieldName<_szName...>, Field<_Value, _szName...>, _OtherFields...> {
		typedef _Value Type;
	};

	template<char const ..._szFieldName, typename _FirstField, typename ..._OtherFields>
	struct FieldType<FieldName<_szFieldName...>, _FirstField, _OtherFields...> {
		typedef typename FieldType<FieldName<_szFieldName...>, _OtherFields...>::Type Type;
	};

	template<typename _Value, char const ..._szName>
	char const Field<_Value, _szName...>::s_szName = { _szName... };

	template<typename ..._Fields>
	struct Object {};

	template<typename _Field, typename ..._Fields>
	struct Getter {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, Field<_Value, _szName...>, _OtherFields...> {
		inline static _Value &Get(Object<Field<_Value, _szName...>, _OtherFields...> &rObject) {
			return rObject.m_Value;
		}

		inline static _Value const &Get(Object<Field<_Value, _szName...>, _OtherFields...> const &rObject) {
			return rObject.m_Value;
		}
	};

	template<typename _Value, char const ..._szName, typename _FirstField, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...> {
		inline static _Value &Get(Object<_FirstField, _OtherFields...> &rObject) {
			return Getter<Field<_Value, _szName...>, _OtherFields...>::Get(rObject);
		}

		inline static _Value const &Get(Object<_FirstField, _OtherFields...> const &rObject) {
			return Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...>::Get(rObject);
		}
	};

	template<>
	struct Object<> {
		Object() {}
		virtual ~Object() {}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Object<Field<_Value, _szName...>, _OtherFields...> :
		public Object<_OtherFields...>
	{
		static char const s_szName[];
		_Value m_Value;

		Object() {}

		virtual ~Object() {}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type &Get() {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type const &Get() const {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	char const Object<Field<_Value, _szName...>, _OtherFields...>::s_szName[] = { _szName... };

	template<typename _Type>
	struct Serializer {
		static _Type Load(istream &ris);
		static ostream &Store(ostream &ros, _Type const &r);
	};

	template<>
	struct Serializer<nullptr_t> {
		static nullptr_t Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, nullptr_t const &r) {
			return ros << "null";
		}
	};

	template<>
	struct Serializer<bool> {
		static bool Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, bool const &r) {
			if (r) {
				return ros << "true";
			} else {
				return ros << "false";
			}
		}
	};

	template<>
	struct Serializer<int> {
		static int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<unsigned int> {
		static unsigned int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, unsigned int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<double> {
		static double Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, double const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<string> {
		static string Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, string const &r) {
			return ros << '\"' << r << '\"'; // FIXME escape special characters
		}
	};

	template<typename ..._Fields>
	struct Serializer<Object<_Fields...>> {
		static Object<_Fields...> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element>
	struct Serializer<vector<_Element>> {
		static vector<_Element> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element, unsigned int _c>
	struct Serializer<array<_Element, _c>> {
		static array<_Element, _c> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Type>
	inline _Type Load(istream &ris) {
		return Serializer<_Type>::Load(ris);
	}

	template<typename _Type>
	inline ostream &Store(ostream &ros, _Type const &r) {
		return Serializer<_Type>::Store(ros, r);
	}
}

template<typename ..._Fields>
inline std::istream &operator >> (std::istream &ris, JSON::Object<_Fields...> &rObject) {
	rObject = JSON::Load<JSON::Object<_Fields...>>(ris);
	return ris;
}

template<typename ..._Fields>
inline std::ostream &operator << (std::ostream &ros, JSON::Object<_Fields...> &rObject) {
	return JSON::Store<JSON::Object<_Fields...>>(ros, rObject);
}

#define UNPACK(sz) (sz)[0], ((sz)[0] > 0) ? UNPACK((sz) + 1) : 0

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: lateinitthread.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-12 08:00:08 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "lateinitthread.hxx"

//_______________________________________________
// includes

//_______________________________________________
// namespace

namespace filter{
    namespace config{

namespace css = ::com::sun::star;

//_______________________________________________
// definitions

/*-----------------------------------------------
    14.08.2003 09:31
-----------------------------------------------*/
LateInitThread::LateInitThread()
{
}

/*-----------------------------------------------
    14.08.2003 08:42
-----------------------------------------------*/
LateInitThread::~LateInitThread()
{
}

/*-----------------------------------------------
    28.10.2003 09:30
-----------------------------------------------*/
void SAL_CALL LateInitThread::run()
{
    try
    {
        // sal_True => It indicates using of this method by this thread
        // The filter cache use this information to show an assertion
        // for "optimization failure" in case the first calli of loadAll()
        // was not this thread ...
        ::salhelper::SingletonRef< FilterCache > rCache;
        rCache->load(FilterCache::E_CONTAINS_ALL);
    }
    catch(const css::uno::Exception&)
    {
        OSL_ENSURE(sal_False, "Filter cache could not be filled successfully! Might this office will run into some trouble ...");
    }
}

    } // namespace config
} // namespace filter
<commit_msg>INTEGRATION: CWS fwklhf01 (1.3.24); FILE MERGED 2004/06/18 13:14:50 as 1.3.24.1: #115305# make shure, that filter cache isnt created more then once ...<commit_after>/*************************************************************************
 *
 *  $RCSfile: lateinitthread.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2004-07-23 11:12:10 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "lateinitthread.hxx"

//_______________________________________________
// includes

//_______________________________________________
// namespace

namespace filter{
    namespace config{

namespace css = ::com::sun::star;

//_______________________________________________
// definitions

/*-----------------------------------------------
    14.08.2003 09:31
-----------------------------------------------*/
LateInitThread::LateInitThread()
{
}

/*-----------------------------------------------
    14.08.2003 08:42
-----------------------------------------------*/
LateInitThread::~LateInitThread()
{
}

/*-----------------------------------------------
    28.10.2003 09:30
-----------------------------------------------*/
void SAL_CALL LateInitThread::run()
{
    // sal_True => It indicates using of this method by this thread
    // The filter cache use this information to show an assertion
    // for "optimization failure" in case the first calli of loadAll()
    // was not this thread ...

    // Further please dont catch any exception here.
    // May be they show the problem of a corrupted filter
    // configuration, which is handled inside our event loop or desktop.main()!

    ::salhelper::SingletonRef< FilterCache > rCache;
    rCache->load(FilterCache::E_CONTAINS_ALL, sal_True);
}

    } // namespace config
} // namespace filter
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2016 LiteIDE Team. All rights reserved.
**
** 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.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: litetabwidget.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "litetabwidget.h"
#include "liteapi/liteapi.h"
#include <QTabBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QStackedLayout>
#include <QStackedWidget>
#include <QToolButton>
#include <QPushButton>
#include <QToolBar>
#include <QAction>
#include <QActionGroup>
#include <QMenu>
#include <QKeyEvent>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

LiteTabWidget::LiteTabWidget(QSize iconSize, QObject *parent) :
    QObject(parent)
{
    m_tabBar = new TabBar;
    m_tabBar->setExpanding(false);
    m_tabBar->setDocumentMode(true);
    m_tabBar->setDrawBase(false);
    m_tabBar->setUsesScrollButtons(true);
    m_tabBar->setMovable(true);
    m_tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);

    m_dumpToolBar = new QToolBar;
    m_dumpToolBar->setObjectName("toolbar.tabs");
    m_dumpToolBar->setIconSize(iconSize);

    m_tabBarWidget = new QWidget;

    m_addTabAct = new QAction(QIcon("icon:images/addpage.png"),tr("Open a new tab"),this);

    m_listButton = new QToolButton(m_dumpToolBar);
    m_listButton->setToolTip(tr("List All Tabs"));
    m_listButton->setIcon(QIcon("icon:images/listpage.png"));
    m_listButton->setPopupMode(QToolButton::InstantPopup);
    m_listButton->setStyleSheet(
                "QToolButton{border:none;}"
                "QToolButton::menu-indicator{image:none;}");

    m_closeTabAct = new QAction(QIcon("icon:images/closetool.png"),tr("Close Tab"),this);
    m_closeButton = new QToolButton(m_dumpToolBar);
    m_closeButton->setDefaultAction(m_closeTabAct);
    m_closeButton->setStyleSheet(
                "QToolButton{border:none;}");

    QHBoxLayout *layout = new QHBoxLayout;
    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(m_tabBar,1);
    layout->addWidget(m_listButton);
    layout->addWidget(m_closeButton);

    m_tabBarWidget->setLayout(layout);

    m_stackedWidget = new QStackedWidget;

    connect(m_tabBar,SIGNAL(currentChanged(int)),this,SLOT(tabCurrentChanged(int)));
    connect(m_tabBar,SIGNAL(tabCloseRequested(int)),this,SIGNAL(tabCloseRequested(int)));
    connect(m_tabBar,SIGNAL(tabMoved(int,int)),this,SLOT(tabMoved(int,int)));
    connect(m_closeTabAct,SIGNAL(triggered()),this,SLOT(closeCurrentTab()));
    connect(m_addTabAct,SIGNAL(triggered()),this,SIGNAL(tabAddRequest()));

    m_listButton->setEnabled(false);
}

LiteTabWidget::~LiteTabWidget()
{
    delete m_tabBarWidget;
    delete m_dumpToolBar;
}

void LiteTabWidget::closeCurrentTab()
{
    int index = m_tabBar->currentIndex();
    if (index < 0) {
        return;
    }
    emit tabCloseRequested(index);
}

int LiteTabWidget::addTab(QWidget *w,const QString & label, const QString &tip)
{
    return addTab(w,QIcon(),label,tip);
}

int LiteTabWidget::addTab(QWidget *w,const QIcon & icon, const QString & label, const QString &tip)
{
    if (!w) {
        return -1;
    }

    if (m_widgetList.size() == 0) {
        m_listButton->setEnabled(true);
    }

    int index = m_tabBar->addTab(icon,label);
    if (!tip.isEmpty()) {
        m_tabBar->setTabToolTip(index,tip);
    }
    m_stackedWidget->addWidget(w);
    m_widgetList.append(w);

    return index;
}

void LiteTabWidget::removeTab(int index)
{
    if (index < 0)
        return;
    QWidget *w = widget(index);
    if (w) {
        m_stackedWidget->removeWidget(w);
        m_widgetList.removeAt(index);
    }

    if (m_widgetList.size() == 0) {
        m_listButton->setEnabled(false);
    }

    m_tabBar->removeTab(index);
}

QWidget *LiteTabWidget::currentWidget()
{
    return m_stackedWidget->currentWidget();
}

TabBar *LiteTabWidget::tabBar()
{
    return m_tabBar;
}

QList<QWidget*> LiteTabWidget::widgetList() const
{
    return m_widgetList;
}

QWidget *LiteTabWidget::stackedWidget()
{
    return m_stackedWidget;
}

QWidget *LiteTabWidget::tabBarWidget()
{
    return m_tabBarWidget;
}

void LiteTabWidget::setListMenu(QMenu *menu)
{
    m_listButton->setMenu(menu);
}

void LiteTabWidget::setTabText(int index, const QString & text)
{
    m_tabBar->setTabText(index,text);
}

int LiteTabWidget::indexOf(QWidget *w)
{
    return m_widgetList.indexOf(w);
}

QWidget *LiteTabWidget::widget(int index)
{
    return m_widgetList.value(index);
}

void LiteTabWidget::setCurrentWidget(QWidget *w)
{
    int index = indexOf(w);
    if (index < 0)
        return;
    setCurrentIndex(index);
}

void LiteTabWidget::tabCurrentChanged(int index)
{
    QWidget *w = m_widgetList.value(index);
    if (w) {
        m_stackedWidget->setCurrentWidget(w);
    }

    emit currentChanged(index);
}

void LiteTabWidget::setCurrentIndex(int index)
{
    m_tabBar->setCurrentIndex(index);
}

void LiteTabWidget::tabMoved(int from, int to)
{
    m_widgetList.swap(from,to);
}
<commit_msg>liteapp update css<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2016 LiteIDE Team. All rights reserved.
**
** 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.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: litetabwidget.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "litetabwidget.h"
#include "liteapi/liteapi.h"
#include <QTabBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QStackedLayout>
#include <QStackedWidget>
#include <QToolButton>
#include <QPushButton>
#include <QToolBar>
#include <QAction>
#include <QActionGroup>
#include <QMenu>
#include <QKeyEvent>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

LiteTabWidget::LiteTabWidget(QSize iconSize, QObject *parent) :
    QObject(parent)
{
    m_tabBar = new TabBar;
    m_tabBar->setExpanding(false);
    m_tabBar->setDocumentMode(true);
    m_tabBar->setDrawBase(false);
    m_tabBar->setUsesScrollButtons(true);
    m_tabBar->setMovable(true);
    m_tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);

    m_dumpToolBar = new QToolBar;
    m_dumpToolBar->setObjectName("toolbar.tabs");
    m_dumpToolBar->setIconSize(iconSize);

    m_tabBarWidget = new QWidget;

    m_addTabAct = new QAction(QIcon("icon:images/addpage.png"),tr("Open a new tab"),this);

    m_listButton = new QToolButton(m_dumpToolBar);
    m_listButton->setToolTip(tr("List All Tabs"));
    m_listButton->setIcon(QIcon("icon:images/listpage.png"));
    m_listButton->setPopupMode(QToolButton::InstantPopup);
#ifdef Q_OS_MAC
    m_listButton->setStyleSheet(
                "QToolButton{border:none;}"
                "QToolButton::menu-indicator{image:none;}");
#else
    m_listButton->setStyleSheet(
                "QToolButton::menu-indicator{image:none;}");
#endif

    m_closeTabAct = new QAction(QIcon("icon:images/closetool.png"),tr("Close Tab"),this);
    m_closeButton = new QToolButton(m_dumpToolBar);
    m_closeButton->setDefaultAction(m_closeTabAct);
#ifdef Q_OS_MAC
    m_closeButton->setStyleSheet(
                "QToolButton{border:none;}");
#endif

    QHBoxLayout *layout = new QHBoxLayout;
    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(m_tabBar,1);
    layout->addWidget(m_listButton);
    layout->addWidget(m_closeButton);

    m_tabBarWidget->setLayout(layout);

    m_stackedWidget = new QStackedWidget;

    connect(m_tabBar,SIGNAL(currentChanged(int)),this,SLOT(tabCurrentChanged(int)));
    connect(m_tabBar,SIGNAL(tabCloseRequested(int)),this,SIGNAL(tabCloseRequested(int)));
    connect(m_tabBar,SIGNAL(tabMoved(int,int)),this,SLOT(tabMoved(int,int)));
    connect(m_closeTabAct,SIGNAL(triggered()),this,SLOT(closeCurrentTab()));
    connect(m_addTabAct,SIGNAL(triggered()),this,SIGNAL(tabAddRequest()));

    m_listButton->setEnabled(false);
}

LiteTabWidget::~LiteTabWidget()
{
    delete m_tabBarWidget;
    delete m_dumpToolBar;
}

void LiteTabWidget::closeCurrentTab()
{
    int index = m_tabBar->currentIndex();
    if (index < 0) {
        return;
    }
    emit tabCloseRequested(index);
}

int LiteTabWidget::addTab(QWidget *w,const QString & label, const QString &tip)
{
    return addTab(w,QIcon(),label,tip);
}

int LiteTabWidget::addTab(QWidget *w,const QIcon & icon, const QString & label, const QString &tip)
{
    if (!w) {
        return -1;
    }

    if (m_widgetList.size() == 0) {
        m_listButton->setEnabled(true);
    }

    int index = m_tabBar->addTab(icon,label);
    if (!tip.isEmpty()) {
        m_tabBar->setTabToolTip(index,tip);
    }
    m_stackedWidget->addWidget(w);
    m_widgetList.append(w);

    return index;
}

void LiteTabWidget::removeTab(int index)
{
    if (index < 0)
        return;
    QWidget *w = widget(index);
    if (w) {
        m_stackedWidget->removeWidget(w);
        m_widgetList.removeAt(index);
    }

    if (m_widgetList.size() == 0) {
        m_listButton->setEnabled(false);
    }

    m_tabBar->removeTab(index);
}

QWidget *LiteTabWidget::currentWidget()
{
    return m_stackedWidget->currentWidget();
}

TabBar *LiteTabWidget::tabBar()
{
    return m_tabBar;
}

QList<QWidget*> LiteTabWidget::widgetList() const
{
    return m_widgetList;
}

QWidget *LiteTabWidget::stackedWidget()
{
    return m_stackedWidget;
}

QWidget *LiteTabWidget::tabBarWidget()
{
    return m_tabBarWidget;
}

void LiteTabWidget::setListMenu(QMenu *menu)
{
    m_listButton->setMenu(menu);
}

void LiteTabWidget::setTabText(int index, const QString & text)
{
    m_tabBar->setTabText(index,text);
}

int LiteTabWidget::indexOf(QWidget *w)
{
    return m_widgetList.indexOf(w);
}

QWidget *LiteTabWidget::widget(int index)
{
    return m_widgetList.value(index);
}

void LiteTabWidget::setCurrentWidget(QWidget *w)
{
    int index = indexOf(w);
    if (index < 0)
        return;
    setCurrentIndex(index);
}

void LiteTabWidget::tabCurrentChanged(int index)
{
    QWidget *w = m_widgetList.value(index);
    if (w) {
        m_stackedWidget->setCurrentWidget(w);
    }

    emit currentChanged(index);
}

void LiteTabWidget::setCurrentIndex(int index)
{
    m_tabBar->setCurrentIndex(index);
}

void LiteTabWidget::tabMoved(int from, int to)
{
    m_widgetList.swap(from,to);
}
<|endoftext|>


<commit_before><commit_msg>Improve logging<commit_after><|endoftext|>


<commit_before><commit_msg>Fix regression introduced by swapping Close and Quit in the messagebox a few lines above. Quit is now KMessageBox::No<commit_after><|endoftext|>


<commit_before>/**
 * \file
 * \brief Scheduler class implementation
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2014-09-16
 */

#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/scheduler/Thread.hpp"
#include "distortos/scheduler/SoftwareTimer.hpp"
#include "distortos/scheduler/MainThreadControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"
#include "distortos/architecture/InterruptUnmaskingLock.hpp"

#include <cerrno>

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

Scheduler::Scheduler(MainThreadControlBlock& mainThreadControlBlock, Thread<void (&)()>& idleThread) :
		currentThreadControlBlock_{},
		threadControlBlockListAllocatorPool_{},
		threadControlBlockListAllocator_{threadControlBlockListAllocatorPool_},
		runnableList_{threadControlBlockListAllocator_, ThreadControlBlock::State::Runnable},
		suspendedList_{threadControlBlockListAllocator_, ThreadControlBlock::State::Suspended},
		softwareTimerControlBlockSupervisor_{},
		tickCount_{0}
{
	add(mainThreadControlBlock);
	currentThreadControlBlock_ = runnableList_.begin();

	idleThread.start();

	architecture::startScheduling();
}

void Scheduler::add(ThreadControlBlock& threadControlBlock)
{
	threadControlBlock.getRoundRobinQuantum().reset();

	architecture::InterruptMaskingLock interruptMaskingLock;
	threadControlBlockListAllocatorPool_.feed(threadControlBlock.getLink());
	runnableList_.sortedEmplace(threadControlBlock);
	maybeRequestContextSwitch();
}

void Scheduler::block(ThreadControlBlockList& container)
{
	block(container, currentThreadControlBlock_);
}

int Scheduler::block(ThreadControlBlockList& container, const ThreadControlBlockListIterator iterator)
{
	{
		architecture::InterruptMaskingLock interruptMaskingLock;

		const auto ret = blockInternal(container, iterator);
		if (ret != 0)
			return ret;

		if (iterator != currentThreadControlBlock_)	// blocked thread is not current thread - no forced switch required
			return 0;
	}

	forceContextSwitch();

	return 0;
}

int Scheduler::blockUntil(ThreadControlBlockList& container, const TickClock::time_point timePoint)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	const auto iterator = currentThreadControlBlock_;
	bool timedOut {};
	// This lambda unblocks the thread only if it wasn't already unblocked - this is necessary because double unblock
	// should be avoided (it could mess the order of threads of the same priority). In that case it also marks the
	// "timed out" reason of unblocking.
	auto softwareTimer = makeSoftwareTimer(
			[this, iterator, &timedOut]()
			{
				if (iterator->get().getList() != &runnableList_)
				{
					unblockInternal(iterator);
					timedOut = true;
				}
			});
	softwareTimer.start(timePoint);

	block(container);

	return timedOut == false ? 0 : ETIMEDOUT;
}

uint64_t Scheduler::getTickCount() const
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return tickCount_;
}

int Scheduler::remove()
{
	{
		architecture::InterruptMaskingLock interruptMaskingLock;
		ThreadControlBlockList terminatedList {threadControlBlockListAllocator_, ThreadControlBlock::State::Terminated};

		const auto ret = blockInternal(terminatedList, currentThreadControlBlock_);
		if (ret != 0)
			return ret;

		terminatedList.begin()->get().terminationHook();
	}

	forceContextSwitch();

	return 0;
}

int Scheduler::resume(const ThreadControlBlockListIterator iterator)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	if (iterator->get().getList() != &suspendedList_)
		return EINVAL;

	unblock(iterator);
	return 0;
}

void Scheduler::suspend()
{
	suspend(currentThreadControlBlock_);
}

int Scheduler::suspend(const ThreadControlBlockListIterator iterator)
{
	return block(suspendedList_, iterator);
}

void* Scheduler::switchContext(void* const stackPointer)
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	getCurrentThreadControlBlock().getStack().setStackPointer(stackPointer);
	currentThreadControlBlock_ = runnableList_.begin();
	return getCurrentThreadControlBlock().getStack().getStackPointer();
}

bool Scheduler::tickInterruptHandler()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	++tickCount_;

	getCurrentThreadControlBlock().getRoundRobinQuantum().decrement();

	// if the object is on the "runnable" list and it used its round-robin quantum, then do the "rotation": move current
	// thread to the end of same-priority group to implement round-robin scheduling
	if (getCurrentThreadControlBlock().getList() == &runnableList_ &&
			getCurrentThreadControlBlock().getRoundRobinQuantum().isZero() == true)
		runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	softwareTimerControlBlockSupervisor_.tickInterruptHandler(TickClock::time_point{TickClock::duration{tickCount_}});

	return isContextSwitchRequired();
}

void Scheduler::unblock(const ThreadControlBlockListIterator iterator)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	unblockInternal(iterator);
	maybeRequestContextSwitch();
}

void Scheduler::yield()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);
	maybeRequestContextSwitch();
}

/*---------------------------------------------------------------------------------------------------------------------+
| private functions
+---------------------------------------------------------------------------------------------------------------------*/

int Scheduler::blockInternal(ThreadControlBlockList& container, const ThreadControlBlockListIterator iterator)
{
	if (iterator->get().getList() != &runnableList_)
		return EINVAL;

	container.sortedSplice(runnableList_, iterator);

	return 0;
}

void Scheduler::forceContextSwitch() const
{
	architecture::InterruptUnmaskingLock interruptUnmaskingLock;
	architecture::requestContextSwitch();
}

bool Scheduler::isContextSwitchRequired() const
{
	// this check must be first, because during early startup currentThreadControlBlock_ is not yet initialized (so
	// futher conditions would dereference nullptr) and no threads are available
	if (runnableList_.size() <= 1)	// no threads or single thread available?
		return false;				// no context switch possible

	if (getCurrentThreadControlBlock().getList() != &runnableList_)
		return true;

	if (runnableList_.begin() != currentThreadControlBlock_)	// is there a higher-priority thread available?
		return true;

	if (getCurrentThreadControlBlock().getRoundRobinQuantum().isZero() == true)
	{
		const auto nextThread = ++runnableList_.begin();
		const auto nextThreadPriority = nextThread->get().getPriority();
		// thread with same priority available?
		if (getCurrentThreadControlBlock().getPriority() == nextThreadPriority)
			return true;	// switch context to do round-robin scheduling
	}

	return false;
}

void Scheduler::maybeRequestContextSwitch() const
{
	if (isContextSwitchRequired() == true)
		architecture::requestContextSwitch();
}

void Scheduler::unblockInternal(const ThreadControlBlockListIterator iterator)
{
	runnableList_.sortedSplice(*iterator->get().getList(), iterator);
	iterator->get().getRoundRobinQuantum().reset();
}

}	// namespace scheduler

}	// namespace distortos
<commit_msg>Scheduler: remove redundant call to RoundRobinQuantum::reset() in Scheduler::add()<commit_after>/**
 * \file
 * \brief Scheduler class implementation
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2014-09-16
 */

#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/scheduler/Thread.hpp"
#include "distortos/scheduler/SoftwareTimer.hpp"
#include "distortos/scheduler/MainThreadControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"
#include "distortos/architecture/InterruptUnmaskingLock.hpp"

#include <cerrno>

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

Scheduler::Scheduler(MainThreadControlBlock& mainThreadControlBlock, Thread<void (&)()>& idleThread) :
		currentThreadControlBlock_{},
		threadControlBlockListAllocatorPool_{},
		threadControlBlockListAllocator_{threadControlBlockListAllocatorPool_},
		runnableList_{threadControlBlockListAllocator_, ThreadControlBlock::State::Runnable},
		suspendedList_{threadControlBlockListAllocator_, ThreadControlBlock::State::Suspended},
		softwareTimerControlBlockSupervisor_{},
		tickCount_{0}
{
	add(mainThreadControlBlock);
	currentThreadControlBlock_ = runnableList_.begin();

	idleThread.start();

	architecture::startScheduling();
}

void Scheduler::add(ThreadControlBlock& threadControlBlock)
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	threadControlBlockListAllocatorPool_.feed(threadControlBlock.getLink());
	runnableList_.sortedEmplace(threadControlBlock);
	maybeRequestContextSwitch();
}

void Scheduler::block(ThreadControlBlockList& container)
{
	block(container, currentThreadControlBlock_);
}

int Scheduler::block(ThreadControlBlockList& container, const ThreadControlBlockListIterator iterator)
{
	{
		architecture::InterruptMaskingLock interruptMaskingLock;

		const auto ret = blockInternal(container, iterator);
		if (ret != 0)
			return ret;

		if (iterator != currentThreadControlBlock_)	// blocked thread is not current thread - no forced switch required
			return 0;
	}

	forceContextSwitch();

	return 0;
}

int Scheduler::blockUntil(ThreadControlBlockList& container, const TickClock::time_point timePoint)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	const auto iterator = currentThreadControlBlock_;
	bool timedOut {};
	// This lambda unblocks the thread only if it wasn't already unblocked - this is necessary because double unblock
	// should be avoided (it could mess the order of threads of the same priority). In that case it also marks the
	// "timed out" reason of unblocking.
	auto softwareTimer = makeSoftwareTimer(
			[this, iterator, &timedOut]()
			{
				if (iterator->get().getList() != &runnableList_)
				{
					unblockInternal(iterator);
					timedOut = true;
				}
			});
	softwareTimer.start(timePoint);

	block(container);

	return timedOut == false ? 0 : ETIMEDOUT;
}

uint64_t Scheduler::getTickCount() const
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return tickCount_;
}

int Scheduler::remove()
{
	{
		architecture::InterruptMaskingLock interruptMaskingLock;
		ThreadControlBlockList terminatedList {threadControlBlockListAllocator_, ThreadControlBlock::State::Terminated};

		const auto ret = blockInternal(terminatedList, currentThreadControlBlock_);
		if (ret != 0)
			return ret;

		terminatedList.begin()->get().terminationHook();
	}

	forceContextSwitch();

	return 0;
}

int Scheduler::resume(const ThreadControlBlockListIterator iterator)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	if (iterator->get().getList() != &suspendedList_)
		return EINVAL;

	unblock(iterator);
	return 0;
}

void Scheduler::suspend()
{
	suspend(currentThreadControlBlock_);
}

int Scheduler::suspend(const ThreadControlBlockListIterator iterator)
{
	return block(suspendedList_, iterator);
}

void* Scheduler::switchContext(void* const stackPointer)
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	getCurrentThreadControlBlock().getStack().setStackPointer(stackPointer);
	currentThreadControlBlock_ = runnableList_.begin();
	return getCurrentThreadControlBlock().getStack().getStackPointer();
}

bool Scheduler::tickInterruptHandler()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	++tickCount_;

	getCurrentThreadControlBlock().getRoundRobinQuantum().decrement();

	// if the object is on the "runnable" list and it used its round-robin quantum, then do the "rotation": move current
	// thread to the end of same-priority group to implement round-robin scheduling
	if (getCurrentThreadControlBlock().getList() == &runnableList_ &&
			getCurrentThreadControlBlock().getRoundRobinQuantum().isZero() == true)
		runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	softwareTimerControlBlockSupervisor_.tickInterruptHandler(TickClock::time_point{TickClock::duration{tickCount_}});

	return isContextSwitchRequired();
}

void Scheduler::unblock(const ThreadControlBlockListIterator iterator)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	unblockInternal(iterator);
	maybeRequestContextSwitch();
}

void Scheduler::yield()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);
	maybeRequestContextSwitch();
}

/*---------------------------------------------------------------------------------------------------------------------+
| private functions
+---------------------------------------------------------------------------------------------------------------------*/

int Scheduler::blockInternal(ThreadControlBlockList& container, const ThreadControlBlockListIterator iterator)
{
	if (iterator->get().getList() != &runnableList_)
		return EINVAL;

	container.sortedSplice(runnableList_, iterator);

	return 0;
}

void Scheduler::forceContextSwitch() const
{
	architecture::InterruptUnmaskingLock interruptUnmaskingLock;
	architecture::requestContextSwitch();
}

bool Scheduler::isContextSwitchRequired() const
{
	// this check must be first, because during early startup currentThreadControlBlock_ is not yet initialized (so
	// futher conditions would dereference nullptr) and no threads are available
	if (runnableList_.size() <= 1)	// no threads or single thread available?
		return false;				// no context switch possible

	if (getCurrentThreadControlBlock().getList() != &runnableList_)
		return true;

	if (runnableList_.begin() != currentThreadControlBlock_)	// is there a higher-priority thread available?
		return true;

	if (getCurrentThreadControlBlock().getRoundRobinQuantum().isZero() == true)
	{
		const auto nextThread = ++runnableList_.begin();
		const auto nextThreadPriority = nextThread->get().getPriority();
		// thread with same priority available?
		if (getCurrentThreadControlBlock().getPriority() == nextThreadPriority)
			return true;	// switch context to do round-robin scheduling
	}

	return false;
}

void Scheduler::maybeRequestContextSwitch() const
{
	if (isContextSwitchRequired() == true)
		architecture::requestContextSwitch();
}

void Scheduler::unblockInternal(const ThreadControlBlockListIterator iterator)
{
	runnableList_.sortedSplice(*iterator->get().getList(), iterator);
	iterator->get().getRoundRobinQuantum().reset();
}

}	// namespace scheduler

}	// namespace distortos
<|endoftext|>


<commit_before>// stress inversion of matrices with varios methods
#include "Math/SMatrix.h"
#include "TMatrixTSym.h"
#include "TDecompChol.h"
#include "TDecompBK.h"

#include "TRandom.h"
#include <vector>
#include <string>
#include <iostream>
#include <cmath>
#include <limits>

#include "TStopwatch.h"

// matrix size
#ifndef N
#define N 5
#endif

bool doSelfTest = true;

//timer
namespace test {

#ifdef REPORT_TIME
   void reportTime( std::string s, double time);
#endif

   void printTime(TStopwatch & time, std::string s) {
      int pr = std::cout.precision(8);
      std::cout << s << "\t" << " time = " << time.RealTime() << "\t(sec)\t"
         //    << time.CpuTime()
                << std::endl;
      std::cout.precision(pr);
   }

   class Timer {

   public:

      Timer(const std::string & s = "") : fName(s), fTime(0)
      {
         fWatch.Start();
      }
      Timer(double & t, const std::string & s = "") : fName(s), fTime(&t)
      {
         fWatch.Start();
      }

      ~Timer() {
         fWatch.Stop();
         printTime(fWatch,fName);
#ifdef REPORT_TIME
         // report time
         reportTime(fName, fWatch.RealTime() );
#endif
         if (fTime) *fTime += fWatch.RealTime();
      }

   private:

      std::string fName;
      double * fTime;
      TStopwatch fWatch;

   };
}

using namespace ROOT::Math;

typedef  SMatrix<double,N,N, MatRepSym<double,N> >  SymMatrix;

// create matrix
template<class M>
M * createMatrix() {
   return new M();
}
// specialized for TMatrix
template<>
TMatrixTSym<double> * createMatrix<TMatrixTSym<double> >() {
   return new TMatrixTSym<double>(N);
}

//print matrix
template<class M>
void printMatrix(const M & m) {
   std::cout << m << std::endl;
}
template<>
void printMatrix<TMatrixTSym<double> >(const TMatrixTSym<double> & m ) {
   m.Print();
}

// generate matrices
template<class M>
void genMatrix(M  & m ) {
   TRandom & r = *gRandom;
   // generate first diagonal elemets
   for (int i = 0; i < N; ++i) {
      double maxVal = i*10000/(N-1) + 1;  // max condition is 10^4
      m(i,i) = r.Uniform(0, maxVal);
   }
   for (int i = 0; i < N; ++i) {
      for (int j = 0; j < i; ++j) {
         double v = 0.3*std::sqrt( m(i,i) * m(j,j) ); // this makes the matrix pos defined
         m(i,j) = r.Uniform(0, v);
         m(j,i) = m(i,j); // needed for TMatrix
      }
   }
}

// generate all matrices
template<class M>
void generate(std::vector<M*> & v) {
   int n = v.size();
   gRandom->SetSeed(111);
   for (int i = 0; i < n; ++i) {
      v[i] = createMatrix<M>();
      genMatrix(*v[i] );
   }
}

struct Choleski {};
struct BK {};
struct QR {};
struct Cramer {};
struct Default {};

template <class M, class Type>
struct TestInverter {
   static bool Inv ( const M & , M & ) { return false;}
   static bool Inv2 ( M & ) { return false;}
};

template <>
struct TestInverter<SymMatrix, Choleski> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.InverseChol(ifail);
      return  ifail == 0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.InvertChol();
   }
};

template <>
struct TestInverter<SymMatrix, BK> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.Inverse(ifail);
      return ifail==0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.Invert();
   }
};

template <>
struct TestInverter<SymMatrix, Cramer> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.InverseFast(ifail);
      return ifail==0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.InvertFast();
   }
};

#ifdef LATER
template <>
struct TestInverter<SymMatrix, QR> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      ROOT::Math::QRDecomposition<double> d;
      int ifail = 0;
      result = m.InverseFast(ifail);
      return ifail==0;
   }
};
#endif

//TMatrix functions

template <>
struct TestInverter<TMatrixDSym, Default> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      result = m;
      result.Invert();
      return true;
   }
   static bool Inv2 ( TMatrixDSym & m ) {
      m.Invert();
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, Cramer> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      result = m;
      result.InvertFast();
      return true;
   }
   static bool Inv2 ( TMatrixDSym & m ) {
      m.InvertFast();
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, Choleski> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      TDecompChol chol(m);
      if (!chol.Decompose() ) return false;
      chol.Invert(result);
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, BK> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      TDecompBK d(m);
      if (!d.Decompose() ) return false;
      d.Invert(result);
      return true;
   }
};

template<class M, class T>
double invert( const std::vector<M* >  & matlist, double & time,std::string s) {
   M result = *(matlist.front());
   test::Timer t(time,s);
   int nloop = matlist.size();
   double sum = 0;
   for (int l = 0; l < nloop; l++)
   {
      const M & m = *(matlist[l]);
      bool ok = TestInverter<M,T>::Inv(m,result);
      if (!ok) {
         std::cout << "inv failed for matrix " << l << std::endl;
         printMatrix<M>( m);
         return -1;
      }
      sum += result(0,1);
   }
   return sum;
}

// invert without copying the matrices (une INv2)

template<class M, class T>
double invert2( const std::vector<M* >  & matlist, double & time,std::string s) {

   // copy vector of matrices
   int nloop = matlist.size();
   std::vector<M *> vmat(nloop);
   for (int l = 0; l < nloop; l++)
   {
      vmat[l] = new M( *matlist[l] );
   }

   test::Timer t(time,s);
   double sum = 0;
   for (int l = 0; l < nloop; l++)
   {
      M & m = *(vmat[l]);
      bool ok = TestInverter<M,T>::Inv2(m);
      if (!ok) {
         std::cout << "inv failed for matrix " << l << std::endl;
         printMatrix<M>( m);
         return -1;
      }
      sum += m(0,1);
   }
   return sum;
}

bool equal(double d1, double d2, double stol = 10000) {
   std::cout.precision(12);  // tolerance is 1E-12
   double eps = stol * std::numeric_limits<double>::epsilon();
   if ( std::abs(d1) > 0 && std::abs(d2) > 0 )
      return  ( std::abs( d1-d2) < eps * std::max(std::abs(d1), std::abs(d2) ) );
   else if ( d1 == 0 )
      return std::abs(d2) < eps;
   else // d2 = 0
      return std::abs(d1) < eps;
}

// test matrices symmetric and positive defines
bool stressSymPosInversion(int n, bool selftest ) {

   // test smatrix

   std::vector<SymMatrix *> v1(n);
   generate(v1);
   std::vector<TMatrixDSym *> v2(n);
   generate(v2);

   bool iret = true;
   double time = 0;
   double s1 = invert<SymMatrix, Choleski> (v1, time,"SMatrix Chol");
   double s2 = invert<SymMatrix, BK> (v1, time,"SMatrix   BK");
   double s3 = invert<SymMatrix, Cramer> (v1, time,"SMatrix Cram");
   bool ok = ( equal(s1,s2) && equal(s1,s3) );
   if (!ok) {
      std::cout << "result SMatrix choleski  " << s1 << " BK   " << s2 << " cramer " << s3 << std::endl;
      std::cerr <<"Error:  inversion test for SMatrix FAILED ! " << std::endl;
   }
   iret  &= ok;
   std::cout << std::endl;

   double m1 = invert<TMatrixDSym, Choleski> (v2, time,"TMatrix Chol");
   double m2 = invert<TMatrixDSym, BK> (v2, time,"TMatrix   BK");
   double m3 = invert<TMatrixDSym, Cramer> (v2, time,"TMatrix Cram");
   double m4 = invert<TMatrixDSym, Default> (v2, time,"TMatrix  Def");

   ok =  ( equal(m1,m2) && equal(m1,m3) && equal(m1,m4) );
   if (!ok) {
      std::cout << "result TMatrix choleski  " << m1 << " BK   " << m2
                << " cramer " << m3 << " default " << m4 << std::endl;
      std::cerr <<"Error:  inversion test for TMatrix FAILED ! " << std::endl;
   }
   iret  &= ok;
   std::cout << std::endl;

      // test using self inversion
   if (selftest) {
      std::cout << "\n - self inversion test \n";
      double s11 = invert2<SymMatrix, Choleski> (v1, time,"SMatrix Chol");
      double s12 = invert2<SymMatrix, BK> (v1, time,"SMatrix   BK");
      double s13 = invert2<SymMatrix, Cramer> (v1, time,"SMatrix Cram");
      ok =  ( equal(s11,s12) && equal(s11,s13) );
      if (!ok) {
         std::cout << "result SMatrix choleski  " << s11 << " BK   " << s12 << " cramer " << s13 << std::endl;
         std::cerr <<"Error:  self inversion test for SMatrix FAILED ! " << std::endl;
      }
      iret  &= ok;
      std::cout << std::endl;

      double m13 = invert2<TMatrixDSym, Cramer> (v2, time,"TMatrix Cram");
      double m14 = invert2<TMatrixDSym, Default> (v2, time,"TMatrix  Def");
      ok =  ( equal(m13,m14)  );
      if (!ok) {
         std::cout << "result TMatrix  cramer " << m13 << " default " << m14 << std::endl;
         std::cerr <<"Error:  self inversion test for TMatrix FAILED ! " << std::endl;
      }
      iret  &= ok;
      std::cout << std::endl;
   }

   return iret;
}

int testInversion(int n = 100000) {
   bool ok = stressSymPosInversion(n, doSelfTest);
   std::cerr << "Test inversion of positive defined matrix ( N = " << N << " ) ........ ";
   if (ok) std::cerr << "OK \n";
   else std::cerr << "FAILED \n";
   return (ok) ? 0 : -1;
}

int main() {
   return testInversion();
}
<commit_msg>fix test error message<commit_after>// stress inversion of matrices with varios methods
#include "Math/SMatrix.h"
#include "TMatrixTSym.h"
#include "TDecompChol.h"
#include "TDecompBK.h"

#include "TRandom.h"
#include <vector>
#include <string>
#include <iostream>
#include <cmath>
#include <limits>

#include "TStopwatch.h"

// matrix size
#ifndef N
#define N 5
#endif

bool doSelfTest = true;

//timer
namespace test {

#ifdef REPORT_TIME
   void reportTime( std::string s, double time);
#endif

   void printTime(TStopwatch & time, std::string s) {
      int pr = std::cout.precision(8);
      std::cout << s << "\t" << " time = " << time.RealTime() << "\t(sec)\t"
         //    << time.CpuTime()
                << std::endl;
      std::cout.precision(pr);
   }

   class Timer {

   public:

      Timer(const std::string & s = "") : fName(s), fTime(0)
      {
         fWatch.Start();
      }
      Timer(double & t, const std::string & s = "") : fName(s), fTime(&t)
      {
         fWatch.Start();
      }

      ~Timer() {
         fWatch.Stop();
         printTime(fWatch,fName);
#ifdef REPORT_TIME
         // report time
         reportTime(fName, fWatch.RealTime() );
#endif
         if (fTime) *fTime += fWatch.RealTime();
      }

   private:

      std::string fName;
      double * fTime;
      TStopwatch fWatch;

   };
}

using namespace ROOT::Math;

typedef  SMatrix<double,N,N, MatRepSym<double,N> >  SymMatrix;

// create matrix
template<class M>
M * createMatrix() {
   return new M();
}
// specialized for TMatrix
template<>
TMatrixTSym<double> * createMatrix<TMatrixTSym<double> >() {
   return new TMatrixTSym<double>(N);
}

//print matrix
template<class M>
void printMatrix(const M & m) {
   std::cout << m << std::endl;
}
template<>
void printMatrix<TMatrixTSym<double> >(const TMatrixTSym<double> & m ) {
   m.Print();
}

// generate matrices
template<class M>
void genMatrix(M  & m ) {
   TRandom & r = *gRandom;
   // generate first diagonal elemets
   for (int i = 0; i < N; ++i) {
      double maxVal = i*10000/(N-1) + 1;  // max condition is 10^4
      m(i,i) = r.Uniform(0, maxVal);
   }
   for (int i = 0; i < N; ++i) {
      for (int j = 0; j < i; ++j) {
         double v = 0.3*std::sqrt( m(i,i) * m(j,j) ); // this makes the matrix pos defined
         m(i,j) = r.Uniform(0, v);
         m(j,i) = m(i,j); // needed for TMatrix
      }
   }
}

// generate all matrices
template<class M>
void generate(std::vector<M*> & v) {
   int n = v.size();
   gRandom->SetSeed(111);
   for (int i = 0; i < n; ++i) {
      v[i] = createMatrix<M>();
      genMatrix(*v[i] );
   }
}

struct Choleski {};
struct BK {};
struct QR {};
struct Cramer {};
struct Default {};

template <class M, class Type>
struct TestInverter {
   static bool Inv ( const M & , M & ) { return false;}
   static bool Inv2 ( M & ) { return false;}
};

template <>
struct TestInverter<SymMatrix, Choleski> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.InverseChol(ifail);
      return  ifail == 0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.InvertChol();
   }
};

template <>
struct TestInverter<SymMatrix, BK> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.Inverse(ifail);
      return ifail==0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.Invert();
   }
};

template <>
struct TestInverter<SymMatrix, Cramer> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      int ifail = 0;
      result = m.InverseFast(ifail);
      return ifail==0;
   }
   static bool Inv2 ( SymMatrix & m ) {
      return m.InvertFast();
   }
};

#ifdef LATER
template <>
struct TestInverter<SymMatrix, QR> {
   static bool Inv ( const SymMatrix & m, SymMatrix & result ) {
      ROOT::Math::QRDecomposition<double> d;
      int ifail = 0;
      result = m.InverseFast(ifail);
      return ifail==0;
   }
};
#endif

//TMatrix functions

template <>
struct TestInverter<TMatrixDSym, Default> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      result = m;
      result.Invert();
      return true;
   }
   static bool Inv2 ( TMatrixDSym & m ) {
      m.Invert();
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, Cramer> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      result = m;
      result.InvertFast();
      return true;
   }
   static bool Inv2 ( TMatrixDSym & m ) {
      m.InvertFast();
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, Choleski> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      TDecompChol chol(m);
      if (!chol.Decompose() ) return false;
      chol.Invert(result);
      return true;
   }
};

template <>
struct TestInverter<TMatrixDSym, BK> {
   static bool Inv ( const TMatrixDSym & m, TMatrixDSym & result ) {
      TDecompBK d(m);
      if (!d.Decompose() ) return false;
      d.Invert(result);
      return true;
   }
};

template<class M, class T>
double invert( const std::vector<M* >  & matlist, double & time,std::string s) {
   M result = *(matlist.front());
   test::Timer t(time,s);
   int nloop = matlist.size();
   double sum = 0;
   for (int l = 0; l < nloop; l++)
   {
      const M & m = *(matlist[l]);
      bool ok = TestInverter<M,T>::Inv(m,result);
      if (!ok) {
         std::cout << "inv failed for matrix " << l << std::endl;
         printMatrix<M>( m);
         return -1;
      }
      sum += result(0,1);
   }
   return sum;
}

// invert without copying the matrices (une INv2)

template<class M, class T>
double invert2( const std::vector<M* >  & matlist, double & time,std::string s) {

   // copy vector of matrices
   int nloop = matlist.size();
   std::vector<M *> vmat(nloop);
   for (int l = 0; l < nloop; l++)
   {
      vmat[l] = new M( *matlist[l] );
   }

   test::Timer t(time,s);
   double sum = 0;
   for (int l = 0; l < nloop; l++)
   {
      M & m = *(vmat[l]);
      bool ok = TestInverter<M,T>::Inv2(m);
      if (!ok) {
         std::cout << "inv failed for matrix " << l << std::endl;
         printMatrix<M>( m);
         return -1;
      }
      sum += m(0,1);
   }
   return sum;
}

bool equal(double d1, double d2, double stol = 10000) {
   std::cout.precision(12);  // tolerance is 1E-12
   double eps = stol * std::numeric_limits<double>::epsilon();
   if ( std::abs(d1) > 0 && std::abs(d2) > 0 )
      return  ( std::abs( d1-d2) < eps * std::max(std::abs(d1), std::abs(d2) ) );
   else if ( d1 == 0 )
      return std::abs(d2) < eps;
   else // d2 = 0
      return std::abs(d1) < eps;
}

// test matrices symmetric and positive defines
bool stressSymPosInversion(int n, bool selftest ) {

   // test smatrix

   std::vector<SymMatrix *> v1(n);
   generate(v1);
   std::vector<TMatrixDSym *> v2(n);
   generate(v2);

   bool iret = true;
   double time = 0;
   double s1 = invert<SymMatrix, Choleski> (v1, time,"SMatrix Chol");
   double s2 = invert<SymMatrix, BK> (v1, time,"SMatrix   BK");
   double s3 = invert<SymMatrix, Cramer> (v1, time,"SMatrix Cram");
   bool ok = ( equal(s1,s2) && equal(s1,s3) );
   if (!ok) {
      std::cout << "result SMatrix choleski  " << s1 << " BK   " << s2 << " cramer " << s3 << std::endl;
      std::cerr <<"Error:  inversion test for SMatrix FAILED ! " << std::endl;
   }
   iret  &= ok;
   std::cout << std::endl;

   double m1 = invert<TMatrixDSym, Choleski> (v2, time,"TMatrix Chol");
   double m2 = invert<TMatrixDSym, BK> (v2, time,"TMatrix   BK");
   double m3 = invert<TMatrixDSym, Cramer> (v2, time,"TMatrix Cram");
   double m4 = invert<TMatrixDSym, Default> (v2, time,"TMatrix  Def");

   ok =  ( equal(m1,m2) && equal(m1,m3) && equal(m1,m4) );
   if (!ok) {
      std::cout << "result TMatrix choleski  " << m1 << " BK   " << m2
                << " cramer " << m3 << " default " << m4 << std::endl;
      std::cerr <<"Error:  inversion test for TMatrix FAILED ! " << std::endl;
   }
   iret  &= ok;
   std::cout << std::endl;

      // test using self inversion
   if (selftest) {
      std::cout << "\n - self inversion test \n";
      double s11 = invert2<SymMatrix, Choleski> (v1, time,"SMatrix Chol");
      double s12 = invert2<SymMatrix, BK> (v1, time,"SMatrix   BK");
      double s13 = invert2<SymMatrix, Cramer> (v1, time,"SMatrix Cram");
      ok =  ( equal(s11,s12) && equal(s11,s13) );
      if (!ok) {
         std::cout << "result SMatrix choleski  " << s11 << " BK   " << s12 << " cramer " << s13 << std::endl;
         std::cerr <<"Error:  self inversion test for SMatrix FAILED ! " << std::endl;
      }
      iret  &= ok;
      std::cout << std::endl;

      double m13 = invert2<TMatrixDSym, Cramer> (v2, time,"TMatrix Cram");
      double m14 = invert2<TMatrixDSym, Default> (v2, time,"TMatrix  Def");
      ok =  ( equal(m13,m14)  );
      if (!ok) {
         std::cout << "result TMatrix  cramer " << m13 << " default " << m14 << std::endl;
         std::cerr <<"Error:  self inversion test for TMatrix FAILED ! " << std::endl;
      }
      iret  &= ok;
      std::cout << std::endl;
   }

   return iret;
}

int testInversion(int n = 100000) {
   std::cout << "Test Inversion for matrix with N = " << N << std::endl;
   bool ok = stressSymPosInversion(n, doSelfTest);
   std::cerr << "Test inversion of positive defined matrix ....... ";
   if (ok) std::cerr << "OK \n";
   else std::cerr << "FAILED \n";
   return (ok) ? 0 : -1;
}

int main() {
   return testInversion();
}
<|endoftext|>