<commit_before>/*
 * Copyright 2015 eje inc.
 * Copyright 2015 Samsung Electronics Co., LTD
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "includes.h"
#include "MeganekkoActivity.h"
#include "RenderData.h"

namespace mgn {
#ifdef __cplusplus
extern "C" {
#endif

long Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeSetAppInterface(
        JNIEnv * jni, jclass clazz, jobject activity,
        jstring fromPackageName, jstring commandString,
        jstring uriString)
{
    return (new MeganekkoActivity())->SetActivity( jni, clazz, activity, fromPackageName, commandString, uriString );
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeHideGazeCursor(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    MeganekkoActivity* activity = (MeganekkoActivity*)((App *)appPtr)->GetAppInterface();
    //activity->GuiSys->GetGazeCursor().HideCursor();
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeShowGazeCursor(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    MeganekkoActivity* activity = (MeganekkoActivity*)((App *)appPtr)->GetAppInterface();
    //activity->GuiSys->GetGazeCursor().ShowCursor();
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_setDebugOptionEnable(JNIEnv * jni, jclass clazz, jboolean enable)
{
    ovr_SetLocalPreferenceValueForKey(LOCAL_PREF_APP_DEBUG_OPTIONS, enable ? "1" : "0");
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_recenterPose(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    ovrMobile * mobile = ((App *)appPtr)->GetOvrMobile();
    vrapi_RecenterPose(mobile);
}

#ifdef __cplusplus
} // extern C
#endif
} // namespace mgn
<commit_msg>Re-enabled showGazeCursor, hideGazeCursor<commit_after>/*
 * Copyright 2015 eje inc.
 * Copyright 2015 Samsung Electronics Co., LTD
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "includes.h"
#include "MeganekkoActivity.h"
#include "RenderData.h"

namespace mgn {
#ifdef __cplusplus
extern "C" {
#endif

long Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeSetAppInterface(
        JNIEnv * jni, jclass clazz, jobject activity,
        jstring fromPackageName, jstring commandString,
        jstring uriString)
{
    return (new MeganekkoActivity())->SetActivity( jni, clazz, activity, fromPackageName, commandString, uriString );
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeHideGazeCursor(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    MeganekkoActivity* activity = (MeganekkoActivity*)((App *)appPtr)->GetAppInterface();
    activity->GuiSys->GetGazeCursor().HideCursor();
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_nativeShowGazeCursor(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    MeganekkoActivity* activity = (MeganekkoActivity*)((App *)appPtr)->GetAppInterface();
    activity->GuiSys->GetGazeCursor().ShowCursor();
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_setDebugOptionEnable(JNIEnv * jni, jclass clazz, jboolean enable)
{
    ovr_SetLocalPreferenceValueForKey(LOCAL_PREF_APP_DEBUG_OPTIONS, enable ? "1" : "0");
}

void Java_com_eje_1c_meganekko_gearvr_MeganekkoActivity_recenterPose(JNIEnv * jni, jclass clazz, jlong appPtr)
{
    ovrMobile * mobile = ((App *)appPtr)->GetOvrMobile();
    vrapi_RecenterPose(mobile);
}

#ifdef __cplusplus
} // extern C
#endif
} // namespace mgn
<|endoftext|>


<commit_before>#include <iostream>
#include <stdlib.h>
#include "Node.h"
#include "LinkedQueue.h"

using namespace std;

LinkedQueue::LinkedQueue(){
	first=NULL;
        last=NULL;
}

LinkedQueue::~LinkedQueue(){
	Node * newNode;
        while (first!=NULL){
        	newNode=first->next;
                delete first;
                first=newNode;
        }
}

bool LinkedQueue::isEmpty(){
	return first==NULL;
}

void LinkedQueue::push(int elem){
	Node * newNode=new Node(elem,NULL);
        if(first==NULL)
        	first=newNode;
        else
        	last->next=newNode;
        last=newNode;
}
int LinkedQueue::pop(){
	if(first==NULL){
        	cout<<"Empty queue, I cannot pop!"<<endl;
                 return 0;
        }
        else{
        	int result = first->value;
                Node * newNode=first->next;
                delete first;
                first=newNode;
                if(first==NULL)
                	last==NULL;
                        return result;

	}

}

void LinkedQueue::printLinkedQueue(){
	if(isEmpty()==true){
		cout<<"Empty queue, I cannot print!"<<endl;
        }
        else{
        	Node * newNode =first;
                int result=first->value;
                while (newNode->next!=NULL){
                	cout<<result<<",";
                        newNode=newNode->next;
                        result=newNode->value;
                }
                cout<<result<<endl;
        }
}

<commit_msg>Adding License to LinkedQueue.cpp<commit_after>/*
    Copyright (C) 2017. faunna

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdlib.h>
#include "Node.h"
#include "LinkedQueue.h"

using namespace std;

LinkedQueue::LinkedQueue(){
	first=NULL;
        last=NULL;
}

LinkedQueue::~LinkedQueue(){
	Node * newNode;
        while (first!=NULL){
        	newNode=first->next;
                delete first;
                first=newNode;
        }
}

bool LinkedQueue::isEmpty(){
	return first==NULL;
}

void LinkedQueue::push(int elem){
	Node * newNode=new Node(elem,NULL);
        if(first==NULL)
        	first=newNode;
        else
        	last->next=newNode;
        last=newNode;
}
int LinkedQueue::pop(){
	if(first==NULL){
        	cout<<"Empty queue, I cannot pop!"<<endl;
                 return 0;
        }
        else{
        	int result = first->value;
                Node * newNode=first->next;
                delete first;
                first=newNode;
                if(first==NULL)
                	last==NULL;
                        return result;

	}

}

void LinkedQueue::printLinkedQueue(){
	if(isEmpty()==true){
		cout<<"Empty queue, I cannot print!"<<endl;
        }
        else{
        	Node * newNode =first;
                int result=first->value;
                while (newNode->next!=NULL){
                	cout<<result<<",";
                        newNode=newNode->next;
                        result=newNode->value;
                }
                cout<<result<<endl;
        }
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *  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: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/*************************************************************************
 * @file
 * Represente index source,index body and index index entry.
 ************************************************************************/
#include    "xfindex.hxx"
#include    "xfparagraph.hxx"

XFIndex::XFIndex()
{
    m_pTitle = NULL;
    m_eType = enumXFIndexTOC;
    m_bProtect = sal_True;
    m_bSeparator = sal_False;
    m_nMaxLevel = 0;

    for(sal_uInt16 i=1;i<MAX_TOC_LEVEL+1;i++)
    {
        m_aTOCSource[i].clear();
    }
}

XFIndex::~XFIndex()
{
    if( m_pTitle )
        delete m_pTitle;

    for(sal_uInt16 i=1;i<MAX_TOC_LEVEL+1;i++)
    {
        m_aTOCSource[i].clear();
    }

    while(m_aTemplates.size()>0)
    {
        XFIndexTemplate * pTemplate = m_aTemplates.back();
        m_aTemplates.pop_back();
        delete pTemplate;pTemplate=NULL;
    }
}

void    XFIndex::AddTemplate(rtl::OUString level, rtl::OUString style, XFIndexTemplate* templ)
{
    templ->SetLevel( level );
    if(m_eType != enumXFIndexTOC) // TOC's styles are applied to template entries separately
    {
        templ->SetStyleName( style );
    }
    m_aTemplates.push_back( templ );
}

void    XFIndex::SetProtected(sal_Bool protect)
{
    m_bProtect = protect;
}

void    XFIndex::SetSeparator(sal_Bool sep)
{
    m_bSeparator = sep;
}

void XFIndex::AddTocSource(sal_uInt16 nLevel, const rtl::OUString sStyleName)
{
    if (nLevel > MAX_TOC_LEVEL)
    {
        return;
    }

    m_aTOCSource[nLevel].push_back(sStyleName);
}

void    XFIndex::ToXml(IXFStream *pStrm)
{
    IXFAttrList *pAttrList = pStrm->GetAttrList();
    pAttrList->Clear();
    rtl::OUString strIndexName;
    rtl::OUString strTplName;
    rtl::OUString strSourceName;

    if(m_eType == enumXFIndexTOC )
    {
        strIndexName = A2OUSTR("text:table-of-content");
        strSourceName = A2OUSTR("text:table-of-content-source");
        strTplName = A2OUSTR("text:table-of-content-entry-template");
    }
    else if( m_eType == enumXFIndexAlphabetical )
    {
        strIndexName = A2OUSTR("text:alphabetical-index");
        strSourceName = A2OUSTR("text:alphabetical-index-source");
        strTplName = A2OUSTR("text:alphabetical-index-entry-template");
    }
    else if( m_eType == enumXFIndexUserIndex )
    {
        strIndexName = A2OUSTR("text:user-index");
        strSourceName = A2OUSTR("text:text:user-index-source");
        strTplName = A2OUSTR("text:user-index-entry-template");
    }
    else if( m_eType == enumXFIndexObject )
    {
        strIndexName = A2OUSTR("text:object-index");
        strSourceName = A2OUSTR("text:object-index-source");
        strTplName = A2OUSTR("text:object-index-entry-template");
    }
    else if( m_eType == enumXFIndexIllustration )
    {
        strIndexName = A2OUSTR("text:illustration-index");
        strSourceName = A2OUSTR("text:illustration-index-source");
        strTplName = A2OUSTR("text:illustration-index-entry-template");
    }
    else if( m_eType == enumXFIndexTableIndex )
    {
        strIndexName = A2OUSTR("text:table-index");
        strSourceName = A2OUSTR("text:table-index-source");
        strTplName = A2OUSTR("text:table-index-entry-template");
    }

    if( !GetStyleName().isEmpty() )
        pAttrList->AddAttribute( A2OUSTR("text:style-name"), GetStyleName() );
    if( m_bProtect )
        pAttrList->AddAttribute( A2OUSTR("text:protected"), A2OUSTR("true") );
    else
        pAttrList->AddAttribute( A2OUSTR("text:protected"), A2OUSTR("false") );

    pAttrList->AddAttribute( A2OUSTR("text:name"), m_strTitle );
    pStrm->StartElement( strIndexName );

    //text:table-of-content-source:
    pAttrList->Clear();

    if(m_eType == enumXFIndexTOC )
    {
        pAttrList->AddAttribute( A2OUSTR("text:outline-level"), Int32ToOUString(10));
        pAttrList->AddAttribute( A2OUSTR("text:use-index-source-styles"), A2OUSTR("true"));
        pAttrList->AddAttribute( A2OUSTR("text:use-index-marks"), A2OUSTR("true"));
        pAttrList->AddAttribute( A2OUSTR("text:use-outline-level"), A2OUSTR("false"));
    }
    if (m_bSeparator)
        pAttrList->AddAttribute( A2OUSTR("text:alphabetical-separators"), A2OUSTR("true") );

    pStrm->StartElement( strSourceName );
    //title template:
    pAttrList->Clear();

    pStrm->StartElement( A2OUSTR("text:index-title-template") );
    pStrm->Characters( m_strTitle );
    pStrm->EndElement( A2OUSTR("text:index-title-template") );

    //entry templates:
    std::vector<XFIndexTemplate *>::iterator it;
    for (it = m_aTemplates.begin(); it != m_aTemplates.end(); ++it)
    {
        (*it)->SetTagName( strTplName);
        (*it)->ToXml(pStrm);
    }

    // by
    if(m_eType == enumXFIndexTOC )
    {
        for(sal_uInt16 i=1; i <= MAX_TOC_LEVEL; i++)
        {
            if (m_aTOCSource[i].empty())
            {
                // unnecessary to output this level
                continue;
            }

            pAttrList->Clear();
            pAttrList->AddAttribute( A2OUSTR("text:outline-level"), Int32ToOUString(i));
            pStrm->StartElement( A2OUSTR("text:index-source-styles") );

            std::vector<rtl::OUString>::iterator it_str;
            for (it_str = m_aTOCSource[i].begin(); it_str != m_aTOCSource[i].end(); ++it)
            {
                pAttrList->Clear();
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), *it_str);
                pStrm->StartElement( A2OUSTR("text:index-source-style") );
                pStrm->EndElement( A2OUSTR("text:index-source-style") );
            }
            pStrm->EndElement( A2OUSTR("text:index-source-styles") );
        }
    }

    pStrm->EndElement( strSourceName );

    //index-body:
    pAttrList->Clear();
    pStrm->StartElement( A2OUSTR("text:index-body") );
    //index-title:
    if(!m_strTitle.isEmpty())
    {
        pAttrList->AddAttribute( A2OUSTR("text:name"), m_strTitle + A2OUSTR("_Head") );
        pStrm->StartElement( A2OUSTR("text:index-title") );
        if( m_pTitle )
            m_pTitle->ToXml(pStrm);
        pStrm->EndElement( A2OUSTR("text:index-title") );
    }

    XFContentContainer::ToXml(pStrm);
    pStrm->EndElement( A2OUSTR("text:index-body") );

    pStrm->EndElement( strIndexName );
}

void XFIndexTemplate::ToXml(IXFStream *pStrm)
{
    IXFAttrList *pAttrList = pStrm->GetAttrList();
    pAttrList->Clear();

    pAttrList->AddAttribute( A2OUSTR("text:outline-level"), m_nLevel );
    pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_strStyle );
    if( m_strTagName.isEmpty() )
        m_strTagName = A2OUSTR("text:table-of-content-entry-template");
    pStrm->StartElement( m_strTagName );

    for( size_t i=0; i<m_aEntries.size(); i++ )
    {
        pAttrList->Clear();

        switch( m_aEntries[i].first )
        {
        case enumXFIndexTemplateChapter:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-chapter-number") );
            pStrm->EndElement( A2OUSTR("text:index-entry-chapter-number") );
            break;
        case enumXFIndexTemplateText:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-text") );
            pStrm->EndElement( A2OUSTR("text:index-entry-text") );
            break;
        case enumXFIndexTemplateTab:
            if( m_eTabType != enumXFTabRight )
                pAttrList->AddAttribute( A2OUSTR("style:position"), DoubleToOUString(m_fTabLength) + A2OUSTR("cm") );

            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            switch(m_eTabType)
            {
            case enumXFTabLeft:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("left") );
                break;
            case enumXFTabCenter:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("center") );
                break;
            case enumXFTabRight:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("right") );
                break;
            case enumXFTabChar:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("char") );
                break;
            default:
                break;
            }
            //delimiter:
            if( m_eTabType == enumXFTabChar )
                pAttrList->AddAttribute( A2OUSTR("style:char"), m_strTabDelimiter );
            //leader char:
            if( !m_strTabLeader.isEmpty() )
                pAttrList->AddAttribute( A2OUSTR("style:leader-char"), m_strTabLeader );

            pStrm->StartElement( A2OUSTR("text:index-entry-tab-stop") );
            pStrm->EndElement( A2OUSTR("text:index-entry-tab-stop") );
            break;
        case enumXFIndexTemplatePage:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-page-number") );
            pStrm->EndElement( A2OUSTR("text:index-entry-page-number") );
            break;
        case enumXFIndexTemplateLinkStart:
            pStrm->StartElement( A2OUSTR("text:index-entry-link-start") );
            pStrm->EndElement( A2OUSTR("text:index-entry-link-start") );
            break;
        case enumXFIndexTemplateLinkEnd:
            pStrm->StartElement( A2OUSTR("text:index-entry-link-end") );
            pStrm->EndElement( A2OUSTR("text:index-entry-link-end") );
            break;
        case enumXFIndexTemplateSpan:
            pAttrList->Clear();
            pAttrList->AddAttribute(A2OUSTR("text:style-name"), GetStyleName());
            pStrm->StartElement( A2OUSTR("text:index-entry-span") );
            pStrm->Characters(m_aTextEntries[i]);
            pStrm->EndElement( A2OUSTR("text:index-entry-span") );
            break;
        case enumXFIndexTemplateBibliography:
            pStrm->StartElement( A2OUSTR("text:index-entry-bibliography") );
            pStrm->EndElement( A2OUSTR("text:index-entry-bibliography") );
            break;
        default:
            break;
        }
    }

    pStrm->EndElement( m_strTagName );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#736014 Using invalid iterator<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *  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: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/*************************************************************************
 * @file
 * Represente index source,index body and index index entry.
 ************************************************************************/
#include    "xfindex.hxx"
#include    "xfparagraph.hxx"

XFIndex::XFIndex()
{
    m_pTitle = NULL;
    m_eType = enumXFIndexTOC;
    m_bProtect = sal_True;
    m_bSeparator = sal_False;
    m_nMaxLevel = 0;

    for(sal_uInt16 i=1;i<MAX_TOC_LEVEL+1;i++)
    {
        m_aTOCSource[i].clear();
    }
}

XFIndex::~XFIndex()
{
    if( m_pTitle )
        delete m_pTitle;

    for(sal_uInt16 i=1;i<MAX_TOC_LEVEL+1;i++)
    {
        m_aTOCSource[i].clear();
    }

    while(m_aTemplates.size()>0)
    {
        XFIndexTemplate * pTemplate = m_aTemplates.back();
        m_aTemplates.pop_back();
        delete pTemplate;pTemplate=NULL;
    }
}

void    XFIndex::AddTemplate(rtl::OUString level, rtl::OUString style, XFIndexTemplate* templ)
{
    templ->SetLevel( level );
    if(m_eType != enumXFIndexTOC) // TOC's styles are applied to template entries separately
    {
        templ->SetStyleName( style );
    }
    m_aTemplates.push_back( templ );
}

void    XFIndex::SetProtected(sal_Bool protect)
{
    m_bProtect = protect;
}

void    XFIndex::SetSeparator(sal_Bool sep)
{
    m_bSeparator = sep;
}

void XFIndex::AddTocSource(sal_uInt16 nLevel, const rtl::OUString sStyleName)
{
    if (nLevel > MAX_TOC_LEVEL)
    {
        return;
    }

    m_aTOCSource[nLevel].push_back(sStyleName);
}

void    XFIndex::ToXml(IXFStream *pStrm)
{
    IXFAttrList *pAttrList = pStrm->GetAttrList();
    pAttrList->Clear();
    rtl::OUString strIndexName;
    rtl::OUString strTplName;
    rtl::OUString strSourceName;

    if(m_eType == enumXFIndexTOC )
    {
        strIndexName = A2OUSTR("text:table-of-content");
        strSourceName = A2OUSTR("text:table-of-content-source");
        strTplName = A2OUSTR("text:table-of-content-entry-template");
    }
    else if( m_eType == enumXFIndexAlphabetical )
    {
        strIndexName = A2OUSTR("text:alphabetical-index");
        strSourceName = A2OUSTR("text:alphabetical-index-source");
        strTplName = A2OUSTR("text:alphabetical-index-entry-template");
    }
    else if( m_eType == enumXFIndexUserIndex )
    {
        strIndexName = A2OUSTR("text:user-index");
        strSourceName = A2OUSTR("text:text:user-index-source");
        strTplName = A2OUSTR("text:user-index-entry-template");
    }
    else if( m_eType == enumXFIndexObject )
    {
        strIndexName = A2OUSTR("text:object-index");
        strSourceName = A2OUSTR("text:object-index-source");
        strTplName = A2OUSTR("text:object-index-entry-template");
    }
    else if( m_eType == enumXFIndexIllustration )
    {
        strIndexName = A2OUSTR("text:illustration-index");
        strSourceName = A2OUSTR("text:illustration-index-source");
        strTplName = A2OUSTR("text:illustration-index-entry-template");
    }
    else if( m_eType == enumXFIndexTableIndex )
    {
        strIndexName = A2OUSTR("text:table-index");
        strSourceName = A2OUSTR("text:table-index-source");
        strTplName = A2OUSTR("text:table-index-entry-template");
    }

    if( !GetStyleName().isEmpty() )
        pAttrList->AddAttribute( A2OUSTR("text:style-name"), GetStyleName() );
    if( m_bProtect )
        pAttrList->AddAttribute( A2OUSTR("text:protected"), A2OUSTR("true") );
    else
        pAttrList->AddAttribute( A2OUSTR("text:protected"), A2OUSTR("false") );

    pAttrList->AddAttribute( A2OUSTR("text:name"), m_strTitle );
    pStrm->StartElement( strIndexName );

    //text:table-of-content-source:
    pAttrList->Clear();

    if(m_eType == enumXFIndexTOC )
    {
        pAttrList->AddAttribute( A2OUSTR("text:outline-level"), Int32ToOUString(10));
        pAttrList->AddAttribute( A2OUSTR("text:use-index-source-styles"), A2OUSTR("true"));
        pAttrList->AddAttribute( A2OUSTR("text:use-index-marks"), A2OUSTR("true"));
        pAttrList->AddAttribute( A2OUSTR("text:use-outline-level"), A2OUSTR("false"));
    }
    if (m_bSeparator)
        pAttrList->AddAttribute( A2OUSTR("text:alphabetical-separators"), A2OUSTR("true") );

    pStrm->StartElement( strSourceName );
    //title template:
    pAttrList->Clear();

    pStrm->StartElement( A2OUSTR("text:index-title-template") );
    pStrm->Characters( m_strTitle );
    pStrm->EndElement( A2OUSTR("text:index-title-template") );

    //entry templates:
    std::vector<XFIndexTemplate *>::iterator it;
    for (it = m_aTemplates.begin(); it != m_aTemplates.end(); ++it)
    {
        (*it)->SetTagName( strTplName);
        (*it)->ToXml(pStrm);
    }

    // by
    if(m_eType == enumXFIndexTOC )
    {
        for(sal_uInt16 i=1; i <= MAX_TOC_LEVEL; i++)
        {
            if (m_aTOCSource[i].empty())
            {
                // unnecessary to output this level
                continue;
            }

            pAttrList->Clear();
            pAttrList->AddAttribute( A2OUSTR("text:outline-level"), Int32ToOUString(i));
            pStrm->StartElement( A2OUSTR("text:index-source-styles") );

            std::vector<rtl::OUString>::iterator it_str;
            for (it_str = m_aTOCSource[i].begin(); it_str != m_aTOCSource[i].end(); ++it_str)
            {
                pAttrList->Clear();
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), *it_str);
                pStrm->StartElement( A2OUSTR("text:index-source-style") );
                pStrm->EndElement( A2OUSTR("text:index-source-style") );
            }
            pStrm->EndElement( A2OUSTR("text:index-source-styles") );
        }
    }

    pStrm->EndElement( strSourceName );

    //index-body:
    pAttrList->Clear();
    pStrm->StartElement( A2OUSTR("text:index-body") );
    //index-title:
    if(!m_strTitle.isEmpty())
    {
        pAttrList->AddAttribute( A2OUSTR("text:name"), m_strTitle + A2OUSTR("_Head") );
        pStrm->StartElement( A2OUSTR("text:index-title") );
        if( m_pTitle )
            m_pTitle->ToXml(pStrm);
        pStrm->EndElement( A2OUSTR("text:index-title") );
    }

    XFContentContainer::ToXml(pStrm);
    pStrm->EndElement( A2OUSTR("text:index-body") );

    pStrm->EndElement( strIndexName );
}

void XFIndexTemplate::ToXml(IXFStream *pStrm)
{
    IXFAttrList *pAttrList = pStrm->GetAttrList();
    pAttrList->Clear();

    pAttrList->AddAttribute( A2OUSTR("text:outline-level"), m_nLevel );
    pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_strStyle );
    if( m_strTagName.isEmpty() )
        m_strTagName = A2OUSTR("text:table-of-content-entry-template");
    pStrm->StartElement( m_strTagName );

    for( size_t i=0; i<m_aEntries.size(); i++ )
    {
        pAttrList->Clear();

        switch( m_aEntries[i].first )
        {
        case enumXFIndexTemplateChapter:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-chapter-number") );
            pStrm->EndElement( A2OUSTR("text:index-entry-chapter-number") );
            break;
        case enumXFIndexTemplateText:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-text") );
            pStrm->EndElement( A2OUSTR("text:index-entry-text") );
            break;
        case enumXFIndexTemplateTab:
            if( m_eTabType != enumXFTabRight )
                pAttrList->AddAttribute( A2OUSTR("style:position"), DoubleToOUString(m_fTabLength) + A2OUSTR("cm") );

            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            switch(m_eTabType)
            {
            case enumXFTabLeft:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("left") );
                break;
            case enumXFTabCenter:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("center") );
                break;
            case enumXFTabRight:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("right") );
                break;
            case enumXFTabChar:
                pAttrList->AddAttribute( A2OUSTR("style:type"), A2OUSTR("char") );
                break;
            default:
                break;
            }
            //delimiter:
            if( m_eTabType == enumXFTabChar )
                pAttrList->AddAttribute( A2OUSTR("style:char"), m_strTabDelimiter );
            //leader char:
            if( !m_strTabLeader.isEmpty() )
                pAttrList->AddAttribute( A2OUSTR("style:leader-char"), m_strTabLeader );

            pStrm->StartElement( A2OUSTR("text:index-entry-tab-stop") );
            pStrm->EndElement( A2OUSTR("text:index-entry-tab-stop") );
            break;
        case enumXFIndexTemplatePage:
            if(!m_aEntries[i].second.isEmpty())
                pAttrList->AddAttribute( A2OUSTR("text:style-name"), m_aEntries[i].second );

            pStrm->StartElement( A2OUSTR("text:index-entry-page-number") );
            pStrm->EndElement( A2OUSTR("text:index-entry-page-number") );
            break;
        case enumXFIndexTemplateLinkStart:
            pStrm->StartElement( A2OUSTR("text:index-entry-link-start") );
            pStrm->EndElement( A2OUSTR("text:index-entry-link-start") );
            break;
        case enumXFIndexTemplateLinkEnd:
            pStrm->StartElement( A2OUSTR("text:index-entry-link-end") );
            pStrm->EndElement( A2OUSTR("text:index-entry-link-end") );
            break;
        case enumXFIndexTemplateSpan:
            pAttrList->Clear();
            pAttrList->AddAttribute(A2OUSTR("text:style-name"), GetStyleName());
            pStrm->StartElement( A2OUSTR("text:index-entry-span") );
            pStrm->Characters(m_aTextEntries[i]);
            pStrm->EndElement( A2OUSTR("text:index-entry-span") );
            break;
        case enumXFIndexTemplateBibliography:
            pStrm->StartElement( A2OUSTR("text:index-entry-bibliography") );
            pStrm->EndElement( A2OUSTR("text:index-entry-bibliography") );
            break;
        default:
            break;
        }
    }

    pStrm->EndElement( m_strTagName );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.1.0, packaged on March, 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*****************************************************************************/

//! \file glc_instance.cpp implementation of the GLC_Instance class.

#include "glc_instance.h"
#include "../shading/glc_selectionmaterial.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

// Default constructor
GLC_Instance::GLC_Instance()
: GLC_Object()
, m_pGeomList(NULL)
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(new int(1))
, m_MatPos()
, m_IsBoundingBoxValid(false)
, m_IsSelected(false)
, m_PolyFace(GL_FRONT_AND_BACK)
, m_PolyMode(GL_FILL)
, m_IsVisible(true)
, m_colorId()
{
	// Encode Color Id
	encodeIdInRGBA();

	//qDebug() << "GLC_Instance::GLC_Instance null instance ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Contruct instance with a geometry
GLC_Instance::GLC_Instance(GLC_VboGeom* pGeom)
: GLC_Object()
, m_pGeomList(new QList<GLC_VboGeom*>())
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(new int(1))
, m_MatPos()
, m_IsBoundingBoxValid(false)
, m_IsSelected(false)
, m_PolyFace(GL_FRONT_AND_BACK)
, m_PolyMode(GL_FILL)
, m_IsVisible(true)
, m_colorId()
{
	m_pGeomList->append(pGeom);
	// Encode Color Id
	encodeIdInRGBA();

	setName(pGeom->name());

	//qDebug() << "GLC_Instance::GLC_Instance ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Copy constructor
GLC_Instance::GLC_Instance(const GLC_Instance& inputNode)
: GLC_Object(inputNode)
, m_pGeomList(inputNode.m_pGeomList)
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(inputNode.m_pNumberOfInstance)
, m_MatPos(inputNode.m_MatPos)
, m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid)
, m_IsSelected(inputNode.m_IsSelected)
, m_PolyFace(inputNode.m_PolyFace)
, m_PolyMode(inputNode.m_PolyMode)
, m_IsVisible(inputNode.m_IsVisible)
, m_colorId()
{
	// Encode Color Id
	encodeIdInRGBA();

	if (NULL != inputNode.m_pBoundingBox)
	{
		m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
	}
	// Increment the number of instance
	++(*m_pNumberOfInstance);
	//qDebug() << "GLC_Instance::GLC_Instance CopyConstructor ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Assignement operator
GLC_Instance& GLC_Instance::operator=(const GLC_Instance& inputNode)
{
	if (this != &inputNode)
	{
		// Clear this instance
		clear();
		m_Uid= inputNode.m_Uid;
		// Encode Color Id
		encodeIdInRGBA();

		m_Name= inputNode.m_Name;

		m_pGeomList= inputNode.m_pGeomList;
		if (NULL != inputNode.m_pBoundingBox)
		{
			m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
		}
		m_pNumberOfInstance= inputNode.m_pNumberOfInstance;
		++(*m_pNumberOfInstance);
		m_MatPos= inputNode.m_MatPos;
		m_IsBoundingBoxValid= inputNode.m_IsBoundingBoxValid;
		m_IsSelected= inputNode.m_IsSelected;
		m_PolyFace= inputNode.m_PolyFace;
		m_PolyMode= inputNode.m_PolyMode;
		m_IsVisible= inputNode.m_IsVisible;

		//qDebug() << "GLC_Instance::operator= :ID = " << m_Uid;
		//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
	}

	return *this;
}

// Destructor
GLC_Instance::~GLC_Instance()
{
	clear();
}

//////////////////////////////////////////////////////////////////////
// Get Functions
//////////////////////////////////////////////////////////////////////

// Get the bounding box
GLC_BoundingBox GLC_Instance::getBoundingBox(void)
{
	GLC_BoundingBox resultBox;
	if (getBoundingBoxValidity())
	{
		resultBox= *m_pBoundingBox;
	}
	else if (m_pGeomList != NULL)
	{
		computeBoundingBox();
		m_IsBoundingBoxValid= true;
		resultBox= *m_pBoundingBox;
	}

	return resultBox;
}

// Get the validity of the Bounding Box
const bool GLC_Instance::getBoundingBoxValidity(void) const
{
	bool result= true;
	if ((m_pGeomList != NULL) && (m_pBoundingBox != NULL))
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result= result and m_pGeomList->at(i)->boundingBoxIsValid() and m_IsBoundingBoxValid;
		}
	}
	else result= false;

	return result;
}

// Clone the instance
GLC_Instance GLC_Instance::clone() const
{
	GLC_Instance cloneInstance;
	if (m_pGeomList != NULL)
	{
		cloneInstance.m_pGeomList= new QList<GLC_VboGeom*>();
		int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			cloneInstance.m_pGeomList->append(m_pGeomList->at(i)->clone());
		}
	}
	if (NULL != m_pBoundingBox)
	{
		cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox);
	}

	cloneInstance.m_MatPos= m_MatPos;
	cloneInstance.m_IsBoundingBoxValid= m_IsBoundingBoxValid;
	cloneInstance.m_IsSelected= m_IsSelected;
	cloneInstance.m_PolyFace= m_PolyFace;
	cloneInstance.m_PolyMode= m_PolyMode;
	cloneInstance.m_IsVisible= m_IsVisible;
	return cloneInstance;
}

// Instanciate the instance
GLC_Instance GLC_Instance::instanciate()
{
	GLC_Instance instance(*this);
	instance.m_Uid= glc::GLC_GenID();
	// Encode Color Id
	encodeIdInRGBA();

	return instance;
}

// Return the GLC_uint decoded ID from RGBA encoded ID
GLC_uint GLC_Instance::decodeRgbId(const GLubyte* pcolorId)
{
	GLC_uint returnId= 0;
	returnId|= (GLC_uint)pcolorId[0] << (0 * 8);
	returnId|= (GLC_uint)pcolorId[1] << (1 * 8);
	returnId|= (GLC_uint)pcolorId[2] << (2 * 8);
	// Only get first 24 bits
	//returnId|= (GLC_uint)pcolorId[3] << (3 * 8);

	return returnId;
}
// Get number of faces
unsigned int GLC_Instance::numberOfFaces() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfFaces();
		}
	}

	return result;
}

// Get number of vertex
unsigned int GLC_Instance::numberOfVertex() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfVertex();
		}
	}

	return result;
}

// Get number of materials
unsigned int GLC_Instance::numberOfMaterials() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfMaterials();
		}
	}

	return result;
}

// Get materials List
QSet<GLC_Material*> GLC_Instance::materialSet() const
{
	QSet<GLC_Material*> result;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result.unite(m_pGeomList->at(i)->materialSet());
		}
	}

	return result;
}

//////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////

// Set the instance Geometry
bool GLC_Instance::setGeometry(GLC_VboGeom* pGeom)
{
	if (NULL != m_pGeomList)
	{
		if (m_pGeomList->contains(pGeom))
		{
			return false;
		}
		else
		{
			m_pGeomList->append(pGeom);
			return true;
		}
	}
	else
	{
		m_pGeomList= new QList<GLC_VboGeom*>();
		m_pGeomList->append(pGeom);
		return true;
	}
}

// Instance translation
GLC_Instance& GLC_Instance::translate(double Tx, double Ty, double Tz)
{
	multMatrix(GLC_Matrix4x4(Tx, Ty, Tz));

	return *this;
}

// Move instance with a 4x4Matrix
GLC_Instance& GLC_Instance::multMatrix(const GLC_Matrix4x4 &MultMat)
{
	m_MatPos= MultMat * m_MatPos;
	m_IsBoundingBoxValid= false;

	return *this;
}

// Replace the instance Matrix
GLC_Instance& GLC_Instance::setMatrix(const GLC_Matrix4x4 &SetMat)
{
	m_MatPos= SetMat;
	m_IsBoundingBoxValid= false;

	return *this;
}

// Reset the instance Matrix
GLC_Instance& GLC_Instance::resetMatrix(void)
{
	m_MatPos.setToIdentity();
	m_IsBoundingBoxValid= false;

	return *this;
}

// Polygon's display style
void GLC_Instance::setPolygonMode(GLenum Face, GLenum Mode)
{
	// Change the polygon mode only if there is a change
	if ((m_PolyFace != Face) || (m_PolyMode != Mode))
	{
		m_PolyFace= Face;
		m_PolyMode= Mode;
	}
}

//////////////////////////////////////////////////////////////////////
// OpenGL Functions
//////////////////////////////////////////////////////////////////////

// All inline

//////////////////////////////////////////////////////////////////////
// private services functions
//////////////////////////////////////////////////////////////////////

// compute the instance bounding box
// m_pGeomList should be not null
void GLC_Instance::computeBoundingBox(void)
{
	if (NULL == m_pGeomList) return;

	if (m_pBoundingBox != NULL)
	{
		delete m_pBoundingBox;
		m_pBoundingBox= NULL;
	}
	m_pBoundingBox= new GLC_BoundingBox();
	const int size= m_pGeomList->size();
	for (int i= 0; i < size; ++i)
	{
		m_pBoundingBox->combine(m_pGeomList->at(i)->boundingBox());
	}

	m_pBoundingBox->transform(m_MatPos);
}

// Clear current instance
void GLC_Instance::clear()
{
	Q_ASSERT(m_pNumberOfInstance != NULL);

	if ((--(*m_pNumberOfInstance)) == 0)
	{
		// this is the last instance, delete the geometry
		if (m_pGeomList != NULL)
		{
			const int size= m_pGeomList->size();
			for (int i= 0; i < size; ++i)
			{
				delete (*m_pGeomList)[i];
			}
			delete m_pGeomList;
			m_pGeomList= NULL;
		}
		// delete instance counter
		//qDebug() << "GLC_Instance::clear ID = " << m_Uid;
		//qDebug() << "- Number of instance" << (*m_pNumberOfInstance);
		delete m_pNumberOfInstance;
		m_pNumberOfInstance= NULL;

	}
	else
	{
		//qDebug() << "GLC_Instance::clear ID = " << m_Uid;
		//qDebug() << " - Number of instance" << (*m_pNumberOfInstance);
	}

	if (m_pBoundingBox != NULL)
	{
		delete m_pBoundingBox;
		m_pBoundingBox= NULL;
	}

	// invalidate the bounding box
	m_IsBoundingBoxValid= false;

}

//! Encode Id to RGBA color
void GLC_Instance::encodeIdInRGBA()
{
	m_colorId[0]= static_cast<GLubyte>((m_Uid >> (0 * 8)) & 0xFF);
	m_colorId[1]= static_cast<GLubyte>((m_Uid >> (1 * 8)) & 0xFF);
	m_colorId[2]= static_cast<GLubyte>((m_Uid >> (2 * 8)) & 0xFF);
	m_colorId[3]= static_cast<GLubyte>((m_Uid >> (3 * 8)) & 0xFF);
}

<commit_msg>Add the possibility to reverse normals of all instance geometries.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.1.0, packaged on March, 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*****************************************************************************/

//! \file glc_instance.cpp implementation of the GLC_Instance class.

#include "glc_instance.h"
#include "../shading/glc_selectionmaterial.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

// Default constructor
GLC_Instance::GLC_Instance()
: GLC_Object()
, m_pGeomList(NULL)
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(new int(1))
, m_MatPos()
, m_IsBoundingBoxValid(false)
, m_IsSelected(false)
, m_PolyFace(GL_FRONT_AND_BACK)
, m_PolyMode(GL_FILL)
, m_IsVisible(true)
, m_colorId()
{
	// Encode Color Id
	encodeIdInRGBA();

	//qDebug() << "GLC_Instance::GLC_Instance null instance ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Contruct instance with a geometry
GLC_Instance::GLC_Instance(GLC_VboGeom* pGeom)
: GLC_Object()
, m_pGeomList(new QList<GLC_VboGeom*>())
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(new int(1))
, m_MatPos()
, m_IsBoundingBoxValid(false)
, m_IsSelected(false)
, m_PolyFace(GL_FRONT_AND_BACK)
, m_PolyMode(GL_FILL)
, m_IsVisible(true)
, m_colorId()
{
	m_pGeomList->append(pGeom);
	// Encode Color Id
	encodeIdInRGBA();

	setName(pGeom->name());

	//qDebug() << "GLC_Instance::GLC_Instance ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Copy constructor
GLC_Instance::GLC_Instance(const GLC_Instance& inputNode)
: GLC_Object(inputNode)
, m_pGeomList(inputNode.m_pGeomList)
, m_pBoundingBox(NULL)
, m_pNumberOfInstance(inputNode.m_pNumberOfInstance)
, m_MatPos(inputNode.m_MatPos)
, m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid)
, m_IsSelected(inputNode.m_IsSelected)
, m_PolyFace(inputNode.m_PolyFace)
, m_PolyMode(inputNode.m_PolyMode)
, m_IsVisible(inputNode.m_IsVisible)
, m_colorId()
{
	// Encode Color Id
	encodeIdInRGBA();

	if (NULL != inputNode.m_pBoundingBox)
	{
		m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
	}
	// Increment the number of instance
	++(*m_pNumberOfInstance);
	//qDebug() << "GLC_Instance::GLC_Instance CopyConstructor ID = " << m_Uid;
	//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
}

// Assignement operator
GLC_Instance& GLC_Instance::operator=(const GLC_Instance& inputNode)
{
	if (this != &inputNode)
	{
		// Clear this instance
		clear();
		m_Uid= inputNode.m_Uid;
		// Encode Color Id
		encodeIdInRGBA();

		m_Name= inputNode.m_Name;

		m_pGeomList= inputNode.m_pGeomList;
		if (NULL != inputNode.m_pBoundingBox)
		{
			m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
		}
		m_pNumberOfInstance= inputNode.m_pNumberOfInstance;
		++(*m_pNumberOfInstance);
		m_MatPos= inputNode.m_MatPos;
		m_IsBoundingBoxValid= inputNode.m_IsBoundingBoxValid;
		m_IsSelected= inputNode.m_IsSelected;
		m_PolyFace= inputNode.m_PolyFace;
		m_PolyMode= inputNode.m_PolyMode;
		m_IsVisible= inputNode.m_IsVisible;

		//qDebug() << "GLC_Instance::operator= :ID = " << m_Uid;
		//qDebug() << "Number of instance" << (*m_pNumberOfInstance);
	}

	return *this;
}

// Destructor
GLC_Instance::~GLC_Instance()
{
	clear();
}

//////////////////////////////////////////////////////////////////////
// Get Functions
//////////////////////////////////////////////////////////////////////

// Get the bounding box
GLC_BoundingBox GLC_Instance::getBoundingBox(void)
{
	GLC_BoundingBox resultBox;
	if (getBoundingBoxValidity())
	{
		resultBox= *m_pBoundingBox;
	}
	else if (m_pGeomList != NULL)
	{
		computeBoundingBox();
		m_IsBoundingBoxValid= true;
		resultBox= *m_pBoundingBox;
	}

	return resultBox;
}

// Get the validity of the Bounding Box
const bool GLC_Instance::getBoundingBoxValidity(void) const
{
	bool result= true;
	if ((m_pGeomList != NULL) && (m_pBoundingBox != NULL))
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result= result and m_pGeomList->at(i)->boundingBoxIsValid() and m_IsBoundingBoxValid;
		}
	}
	else result= false;

	return result;
}

// Clone the instance
GLC_Instance GLC_Instance::clone() const
{
	GLC_Instance cloneInstance;
	if (m_pGeomList != NULL)
	{
		cloneInstance.m_pGeomList= new QList<GLC_VboGeom*>();
		int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			cloneInstance.m_pGeomList->append(m_pGeomList->at(i)->clone());
		}
	}
	if (NULL != m_pBoundingBox)
	{
		cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox);
	}

	cloneInstance.m_MatPos= m_MatPos;
	cloneInstance.m_IsBoundingBoxValid= m_IsBoundingBoxValid;
	cloneInstance.m_IsSelected= m_IsSelected;
	cloneInstance.m_PolyFace= m_PolyFace;
	cloneInstance.m_PolyMode= m_PolyMode;
	cloneInstance.m_IsVisible= m_IsVisible;
	return cloneInstance;
}

// Instanciate the instance
GLC_Instance GLC_Instance::instanciate()
{
	GLC_Instance instance(*this);
	instance.m_Uid= glc::GLC_GenID();
	// Encode Color Id
	encodeIdInRGBA();

	return instance;
}

// Return the GLC_uint decoded ID from RGBA encoded ID
GLC_uint GLC_Instance::decodeRgbId(const GLubyte* pcolorId)
{
	GLC_uint returnId= 0;
	returnId|= (GLC_uint)pcolorId[0] << (0 * 8);
	returnId|= (GLC_uint)pcolorId[1] << (1 * 8);
	returnId|= (GLC_uint)pcolorId[2] << (2 * 8);
	// Only get first 24 bits
	//returnId|= (GLC_uint)pcolorId[3] << (3 * 8);

	return returnId;
}
// Get number of faces
unsigned int GLC_Instance::numberOfFaces() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfFaces();
		}
	}

	return result;
}

// Get number of vertex
unsigned int GLC_Instance::numberOfVertex() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfVertex();
		}
	}

	return result;
}

// Get number of materials
unsigned int GLC_Instance::numberOfMaterials() const
{
	unsigned int result= 0;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result+= m_pGeomList->at(i)->numberOfMaterials();
		}
	}

	return result;
}

// Get materials List
QSet<GLC_Material*> GLC_Instance::materialSet() const
{
	QSet<GLC_Material*> result;
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			result.unite(m_pGeomList->at(i)->materialSet());
		}
	}

	return result;
}

//////////////////////////////////////////////////////////////////////
// Set Functions
//////////////////////////////////////////////////////////////////////

// Set the instance Geometry
bool GLC_Instance::setGeometry(GLC_VboGeom* pGeom)
{
	if (NULL != m_pGeomList)
	{
		if (m_pGeomList->contains(pGeom))
		{
			return false;
		}
		else
		{
			m_pGeomList->append(pGeom);
			return true;
		}
	}
	else
	{
		m_pGeomList= new QList<GLC_VboGeom*>();
		m_pGeomList->append(pGeom);
		return true;
	}
}

// Reverse geometry normals
void GLC_Instance::reverseGeometriesNormals()
{
	if (NULL != m_pGeomList)
	{
		const int size= m_pGeomList->size();
		for (int i= 0; i < size; ++i)
		{
			(*m_pGeomList)[i]->reverseNormals();
		}
	}
}

// Instance translation
GLC_Instance& GLC_Instance::translate(double Tx, double Ty, double Tz)
{
	multMatrix(GLC_Matrix4x4(Tx, Ty, Tz));

	return *this;
}

// Move instance with a 4x4Matrix
GLC_Instance& GLC_Instance::multMatrix(const GLC_Matrix4x4 &MultMat)
{
	m_MatPos= MultMat * m_MatPos;
	m_IsBoundingBoxValid= false;

	return *this;
}

// Replace the instance Matrix
GLC_Instance& GLC_Instance::setMatrix(const GLC_Matrix4x4 &SetMat)
{
	m_MatPos= SetMat;
	m_IsBoundingBoxValid= false;

	return *this;
}

// Reset the instance Matrix
GLC_Instance& GLC_Instance::resetMatrix(void)
{
	m_MatPos.setToIdentity();
	m_IsBoundingBoxValid= false;

	return *this;
}

// Polygon's display style
void GLC_Instance::setPolygonMode(GLenum Face, GLenum Mode)
{
	// Change the polygon mode only if there is a change
	if ((m_PolyFace != Face) || (m_PolyMode != Mode))
	{
		m_PolyFace= Face;
		m_PolyMode= Mode;
	}
}

//////////////////////////////////////////////////////////////////////
// OpenGL Functions
//////////////////////////////////////////////////////////////////////

// All inline

//////////////////////////////////////////////////////////////////////
// private services functions
//////////////////////////////////////////////////////////////////////

// compute the instance bounding box
// m_pGeomList should be not null
void GLC_Instance::computeBoundingBox(void)
{
	if (NULL == m_pGeomList) return;

	if (m_pBoundingBox != NULL)
	{
		delete m_pBoundingBox;
		m_pBoundingBox= NULL;
	}
	m_pBoundingBox= new GLC_BoundingBox();
	const int size= m_pGeomList->size();
	for (int i= 0; i < size; ++i)
	{
		m_pBoundingBox->combine(m_pGeomList->at(i)->boundingBox());
	}

	m_pBoundingBox->transform(m_MatPos);
}

// Clear current instance
void GLC_Instance::clear()
{
	Q_ASSERT(m_pNumberOfInstance != NULL);

	if ((--(*m_pNumberOfInstance)) == 0)
	{
		// this is the last instance, delete the geometry
		if (m_pGeomList != NULL)
		{
			const int size= m_pGeomList->size();
			for (int i= 0; i < size; ++i)
			{
				delete (*m_pGeomList)[i];
			}
			delete m_pGeomList;
			m_pGeomList= NULL;
		}
		// delete instance counter
		//qDebug() << "GLC_Instance::clear ID = " << m_Uid;
		//qDebug() << "- Number of instance" << (*m_pNumberOfInstance);
		delete m_pNumberOfInstance;
		m_pNumberOfInstance= NULL;

	}
	else
	{
		//qDebug() << "GLC_Instance::clear ID = " << m_Uid;
		//qDebug() << " - Number of instance" << (*m_pNumberOfInstance);
	}

	if (m_pBoundingBox != NULL)
	{
		delete m_pBoundingBox;
		m_pBoundingBox= NULL;
	}

	// invalidate the bounding box
	m_IsBoundingBoxValid= false;

}

//! Encode Id to RGBA color
void GLC_Instance::encodeIdInRGBA()
{
	m_colorId[0]= static_cast<GLubyte>((m_Uid >> (0 * 8)) & 0xFF);
	m_colorId[1]= static_cast<GLubyte>((m_Uid >> (1 * 8)) & 0xFF);
	m_colorId[2]= static_cast<GLubyte>((m_Uid >> (2 * 8)) & 0xFF);
	m_colorId[3]= static_cast<GLubyte>((m_Uid >> (3 * 8)) & 0xFF);
}

<|endoftext|>


<commit_before>#include "lqt_qt.hpp"

int lqtL_qt_metacall (lua_State *L, QObject *self,
			QMetaObject::Call call, const char *name,
			int index, void **args) {
	QObject *call_helper = (QObject*)NULL;
        lua_getfield(L, LUA_REGISTRYINDEX, LQT_METACALLER);
        if (lua_islightuserdata(L, -1)) {
                call_helper = (QObject*)lua_touserdata(L, -1);
        }
        lua_pop(L, 1);
        if (call_helper!=NULL) {
                int callindex = 0, oldtop = 0;
                oldtop = lua_gettop(L);
                lqtL_pushudata(L, self, name); // (1)
                lua_getfield(L, -1, LQT_OBJSIGS); // (2)
                //qDebug() << lua_gettop(L) << luaL_typename(L, -1);
                lua_rawgeti(L, -1, index + 1); // (3)
                if (!lua_isstring(L, -1)) {
                        lua_pop(L, 3); // (0)
                        lua_settop(L, oldtop); // (0)
                        QMetaObject::activate(self, self->metaObject(), index, args);
                } else {
                        callindex = call_helper->metaObject()->indexOfSlot(lua_tostring(L, -1));
                        lua_pop(L, 2); // (1)
                        lua_getfield(L, -1, LQT_OBJSLOTS); // (2)
                        lua_rawgeti(L, -1, index+1); // (3)
                        lua_remove(L, -2); // (2)
                        index = call_helper->qt_metacall(call, callindex, args);
                }
        }
        //qDebug() << "no call_helper found";
        return -1;
}

const char add_method_func[] =
"return function(qobj, qname, signature, func)\n"
"	local stringdata = qobj['"LQT_OBJMETASTRING"']\n"
"	local data = qobj['"LQT_OBJMETADATA"']\n"
"	local slots = qobj['"LQT_OBJSLOTS"']\n"
"	local sigs = qobj['"LQT_OBJSIGS"']\n"
"	if stringdata==nil then\n"
"		--print'adding a slot!'\n"
"		--initialize\n"
"		stringdata = qname..'\\0'\n"
"		data = setmetatable({}, {__index=table})\n"
"		data:insert(1) -- revision\n"
"		data:insert(0) -- class name\n"
"		data:insert(0) -- class info (1)\n"
"		data:insert(0) -- class info (2)\n"
"		data:insert(0) -- number of methods\n"
"		data:insert(10) -- beginning of methods\n"
"		data:insert(0) -- number of properties\n"
"		data:insert(0) -- beginning of properties\n"
"		data:insert(0) -- number of enums/sets\n"
"		data:insert(0) -- beginning of enums/sets\n"
"		slots = setmetatable({}, {__index=table})\n"
"		sigs = setmetatable({}, {__index=table})\n"
"	end\n"
"	local name, args = string.match(signature, '^(.*)(%b())$')\n"
"	local arg_list = ''\n"
"	if args=='()' then\n"
"		arg_list=''\n"
"	else\n"
"		local argnum = select(2, string.gsub(args, '.+,', ','))+1\n"
"		for i = 1, argnum do\n"
"			if i>1 then arg_list=arg_list..', ' end\n"
"			arg_list = arg_list .. 'arg' .. i\n"
"		end\n"
"	end\n"
"	--print(arg_list, signature)\n"
"	local sig, params = #stringdata + #arg_list + 1, #stringdata -- , ty, tag, flags\n"
"	stringdata = stringdata .. arg_list .. '\\0' .. signature .. '\\0'\n"
"	data:insert(sig) -- print(sig, string.byte(stringdata, sig, sig+4), string.char(string.byte(stringdata, sig+1, sig+6)))\n"
"	data:insert(params) -- print(params, string.char(string.byte(stringdata, params+1, params+10)))\n"
"	data:insert(#stringdata-1) -- print(#stringdata-1, (string.byte(stringdata, #stringdata)))\n"
"	data:insert(#stringdata-1) -- print(#stringdata-1, (string.byte(stringdata, #stringdata)))\n"
"	if func then\n"
"		data:insert(0x0a)\n"
"		slots:insert(func)\n"
"		sigs:insert('__slot'..signature:match'%b()')\n"
"	else\n"
"		data:insert(0x05)\n"
"		slots:insert(false)\n"
"		sigs:insert(false)\n"
"	end\n"
"	data[5] = data[5] + 1\n"
"	qobj['Lqt MetaStringData'] = stringdata\n"
"	qobj['Lqt MetaData'] = data\n"
"	qobj['Lqt Slots'] = slots\n"
"	qobj['Lqt Signatures'] = sigs\n"
"end\n";

void lqtL_pushaddmethod (lua_State *L) {
	luaL_dostring(L, add_method_func);
}

<commit_msg>use macros instead of hardcoded strings<commit_after>#include "lqt_qt.hpp"

int lqtL_qt_metacall (lua_State *L, QObject *self,
			QMetaObject::Call call, const char *name,
			int index, void **args) {
	QObject *call_helper = (QObject*)NULL;
        lua_getfield(L, LUA_REGISTRYINDEX, LQT_METACALLER);
        if (lua_islightuserdata(L, -1)) {
                call_helper = (QObject*)lua_touserdata(L, -1);
        }
        lua_pop(L, 1);
        if (call_helper!=NULL) {
                int callindex = 0, oldtop = 0;
                oldtop = lua_gettop(L);
                lqtL_pushudata(L, self, name); // (1)
                lua_getfield(L, -1, LQT_OBJSIGS); // (2)
                //qDebug() << lua_gettop(L) << luaL_typename(L, -1);
                lua_rawgeti(L, -1, index + 1); // (3)
                if (!lua_isstring(L, -1)) {
                        lua_pop(L, 3); // (0)
                        lua_settop(L, oldtop); // (0)
                        QMetaObject::activate(self, self->metaObject(), index, args);
                } else {
                        callindex = call_helper->metaObject()->indexOfSlot(lua_tostring(L, -1));
                        lua_pop(L, 2); // (1)
                        lua_getfield(L, -1, LQT_OBJSLOTS); // (2)
                        lua_rawgeti(L, -1, index+1); // (3)
                        lua_remove(L, -2); // (2)
                        index = call_helper->qt_metacall(call, callindex, args);
                }
        }
        //qDebug() << "no call_helper found";
        return -1;
}

const char add_method_func[] =
"return function(qobj, qname, signature, func)\n"
"	local stringdata = qobj['"LQT_OBJMETASTRING"']\n"
"	local data = qobj['"LQT_OBJMETADATA"']\n"
"	local slots = qobj['"LQT_OBJSLOTS"']\n"
"	local sigs = qobj['"LQT_OBJSIGS"']\n"
"	if stringdata==nil then\n"
"		--print'adding a slot!'\n"
"		--initialize\n"
"		stringdata = qname..'\\0'\n"
"		data = setmetatable({}, {__index=table})\n"
"		data:insert(1) -- revision\n"
"		data:insert(0) -- class name\n"
"		data:insert(0) -- class info (1)\n"
"		data:insert(0) -- class info (2)\n"
"		data:insert(0) -- number of methods\n"
"		data:insert(10) -- beginning of methods\n"
"		data:insert(0) -- number of properties\n"
"		data:insert(0) -- beginning of properties\n"
"		data:insert(0) -- number of enums/sets\n"
"		data:insert(0) -- beginning of enums/sets\n"
"		slots = setmetatable({}, {__index=table})\n"
"		sigs = setmetatable({}, {__index=table})\n"
"	end\n"
"	local name, args = string.match(signature, '^(.*)(%b())$')\n"
"	local arg_list = ''\n"
"	if args=='()' then\n"
"		arg_list=''\n"
"	else\n"
"		local argnum = select(2, string.gsub(args, '.+,', ','))+1\n"
"		for i = 1, argnum do\n"
"			if i>1 then arg_list=arg_list..', ' end\n"
"			arg_list = arg_list .. 'arg' .. i\n"
"		end\n"
"	end\n"
"	--print(arg_list, signature)\n"
"	local sig, params = #stringdata + #arg_list + 1, #stringdata -- , ty, tag, flags\n"
"	stringdata = stringdata .. arg_list .. '\\0' .. signature .. '\\0'\n"
"	data:insert(sig) -- print(sig, string.byte(stringdata, sig, sig+4), string.char(string.byte(stringdata, sig+1, sig+6)))\n"
"	data:insert(params) -- print(params, string.char(string.byte(stringdata, params+1, params+10)))\n"
"	data:insert(#stringdata-1) -- print(#stringdata-1, (string.byte(stringdata, #stringdata)))\n"
"	data:insert(#stringdata-1) -- print(#stringdata-1, (string.byte(stringdata, #stringdata)))\n"
"	if func then\n"
"		data:insert(0x0a)\n"
"		slots:insert(func)\n"
"		sigs:insert('__slot'..signature:match'%b()')\n"
"	else\n"
"		data:insert(0x05)\n"
"		slots:insert(false)\n"
"		sigs:insert(false)\n"
"	end\n"
"	data[5] = data[5] + 1\n"
"	qobj['"LQT_OBJMETASTRING"'] = stringdata\n"
"	qobj['"LQT_OBJMETADATA"'] = data\n"
"	qobj['"LQT_OBJSLOTS"'] = slots\n"
"	qobj['"LQT_OBJSIGS"'] = sigs\n"
"end\n";

void lqtL_pushaddmethod (lua_State *L) {
	luaL_dostring(L, add_method_func);
}

<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・TimerRC I/O 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "system.hpp"
#include "intr.hpp"
#include "timer_rc.hpp"

/// F_CLK はタイマー周期計算で必要で、設定が無いとエラーにします。
#ifndef F_CLK
#  error "trc_io.hpp requires F_CLK to be defined"
#endif

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  TimerRC I/O 制御クラス
		@param[in]	TASK 割り込み内で実行されるクラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class TASK>
	class trc_io {

		static TASK task_;

	public:
		static INTERRUPT_FUNC void itask() {
			task_();
		}

	private:

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		trc_io() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭモード開始（最大３チャネルのＰＷＭ出力）
			@param[in]	limit	リミット
			@param[in]	cks		クロック選択（0:f1, 1:f2, 2:f4, 3:f8, 4:f32）
			@param[in]	pfl ポートの初期レベル「fasle」0->1、「true」1->0
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
			@return 設定範囲を超えたら「false」
		*/
		//-----------------------------------------------------------------//
		void start_pwm(uint16_t limit, uint8_t cks, bool pfl, uint8_t ir_lvl = 0) const {
			MSTCR.MSTTRC = 0;  // モジュールスタンバイ解除

			TRCMR.CTS = 0;  // カウント停止

			TRCCNT = 0x0000;
			TRCGRA = limit;

			TRCMR = TRCMR.PWM2.b(1) | TRCMR.PWMB.b(1) | TRCMR.PWMC.b(1) | TRCMR.PWMD.b(1);

			// コンペア一致Ａでカウンタクリア
			TRCCR1 = TRCCR1.CCLR.b(1) | TRCCR1.TOA.b(0) | TRCCR1.CKS.b(cks)
				   | TRCCR1.TOB.b(0) | TRCCR1.TOC.b(0) | TRCCR1.TOD.b(0);

			TRCIOR0 = TRCIOR0.IOA.b(0) | TRCIOR0.IOB.b(2);
			TRCIOR1 = TRCIOR1.IOC.b(8 | 2) | TRCIOR1.IOD.b(8 | 2);

			TRCCR2 = TRCCR2.POLB.b(pfl) | TRCCR2.POLC.b(pfl) | TRCCR2.POLD.b(pfl);

			TRCOER = TRCOER.EB.b(0) | TRCOER.EC.b(0) | TRCOER.ED.b(0);

			ILVLB.B01 = ir_lvl;
			if(ir_lvl) {
				//TRJIR = TRJIR.TRJIE.b(1);
			} else {
				//TRJIR = TRJIR.TRJIE.b(0);
			}

			TRCMR.CTS = 1;  // カウント開始
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭモード開始（最大３チャネルのＰＷＭ出力）
			@param[in]	hz	周期（周波数）
			@param[in]	pfl ポートの初期レベル「fasle」0->1、「true」1->0
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
			@return 設定範囲を超えたら「false」
		*/
		//-----------------------------------------------------------------//
		bool start_pwm(uint16_t hz, bool pfl, uint8_t ir_lvl = 0) const {

			uint32_t tn = F_CLK / hz;
			uint8_t cks = 0;
			while(tn > 65536) {
				tn >>= 1;
				++cks;
				if(cks == 4) {
					tn >>= 1;
				}
				if(cks >= 5) return false;
			}
			if(tn) --tn;
			if(tn == 0) return false;

			start_pwm(tn, cks, pfl, ir_lvl);

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭリミット値を取得
			@return リミット値
		*/
		//-----------------------------------------------------------------//
		uint16_t get_pwm_limit() const {
			return TRCGRA();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｂを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_b(uint16_t val) const {
			TRCGRB = val;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｃを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_c(uint16_t val) const {
			TRCGRC = val;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｄを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_d(uint16_t val) const {
			TRCGRD = val;
		}

	};
}
<commit_msg>Update interrupt<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・TimerRC I/O 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "system.hpp"
#include "intr.hpp"
#include "timer_rc.hpp"

/// F_CLK はタイマー周期計算で必要で、設定が無いとエラーにします。
#ifndef F_CLK
#  error "trc_io.hpp requires F_CLK to be defined"
#endif

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  TimerRC I/O 制御クラス
		@param[in]	TASK 割り込み内で実行されるクラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class TASK>
	class trc_io {

		static TASK task_;

	public:
		static volatile uint16_t	pwm_b_;
		static volatile uint16_t	pwm_c_;
		static volatile uint16_t	pwm_d_;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  PWM-A 割り込み
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		static INTERRUPT_FUNC void itask() {
			task_();
			TRCGRB = pwm_b_;
			TRCGRC = pwm_c_;
			TRCGRD = pwm_d_;
			volatile uint8_t tmp = TRCSR();
			TRCSR = 0x00;
		}

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  カウンターディバイド
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class divide : uint8_t {
			f1,		/// 1 / 1
			f2,		/// 1 / 2
			f4,		/// 1 / 4
			f8,		/// 1 / 8
			f32		/// 1 / 32
		};

	private:

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		trc_io() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭモード開始（最大３チャネルのＰＷＭ出力）
			@param[in]	limit	リミット
			@param[in]	cks		クロック選択
			@param[in]	pfl ポートの初期レベル「fasle」0->1、「true」1->0
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
			@return 設定範囲を超えたら「false」
		*/
		//-----------------------------------------------------------------//
		void start_pwm(uint16_t limit, divide cks, bool pfl, uint8_t ir_lvl = 0) const {
			MSTCR.MSTTRC = 0;  // モジュールスタンバイ解除

			TRCMR.CTS = 0;  // カウント停止

			TRCCNT = 0x0000;
			TRCGRA = limit;

			TRCMR = TRCMR.PWM2.b(1) | TRCMR.PWMB.b(1) | TRCMR.PWMC.b(1) | TRCMR.PWMD.b(1);

			// コンペア一致Ａでカウンタクリア
			TRCCR1 = TRCCR1.CCLR.b(1) | TRCCR1.TOA.b(0) | TRCCR1.CKS.b(static_cast<uint8_t>(cks))
				   | TRCCR1.TOB.b(0) | TRCCR1.TOC.b(0) | TRCCR1.TOD.b(0);

			TRCIOR0 = TRCIOR0.IOA.b(0) | TRCIOR0.IOB.b(2);
			TRCIOR1 = TRCIOR1.IOC.b(8 | 2) | TRCIOR1.IOD.b(8 | 2);

			TRCCR2 = TRCCR2.POLB.b(pfl) | TRCCR2.POLC.b(pfl) | TRCCR2.POLD.b(pfl);

			TRCOER = TRCOER.EB.b(0) | TRCOER.EC.b(0) | TRCOER.ED.b(0);

			ILVL3.B45 = ir_lvl;
			if(ir_lvl) {
				TRCIER = TRCIER.IMIEA.b(1);
			} else {
				TRCIER = 0x00;
			}

			TRCMR.CTS = 1;  // カウント開始
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭモード開始（最大３チャネルのＰＷＭ出力）
			@param[in]	hz	周期（周波数）
			@param[in]	pfl ポートの初期レベル「fasle」0->1、「true」1->0
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
			@return 設定範囲を超えたら「false」
		*/
		//-----------------------------------------------------------------//
		bool start_pwm(uint16_t hz, bool pfl, uint8_t ir_lvl = 0) const {

			uint32_t tn = F_CLK / hz;
			uint8_t cks = 0;
			while(tn > 65536) {
				tn >>= 1;
				++cks;
				if(cks == 4) {
					tn >>= 1;
				}
				if(cks >= 5) return false;
			}
			if(tn) --tn;
			if(tn == 0) return false;

			start_pwm(tn, cks, pfl, ir_lvl);

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭリミット値を取得
			@return リミット値
		*/
		//-----------------------------------------------------------------//
		uint16_t get_pwm_limit() const {
			return TRCGRA();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｂを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_b(uint16_t val) const {
			if(ILVL3.B45()) {
				pwm_b_ = val;
			} else {
				TRCGRB = val;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｃを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_c(uint16_t val) const {
			if(ILVL3.B45()) {
				pwm_c_ = val;
			} else {
				TRCGRC = val;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  ＰＷＭ値Ｄを設定
			@param[in]	val	値
		*/
		//-----------------------------------------------------------------//
		void set_pwm_d(uint16_t val) const {
			if(ILVL3.B45()) {
				pwm_d_ = val;
			} else {
				TRCGRD = val;
			}
		}

	};

	// スタティック実態定義
	template<class TASK>
	volatile uint16_t trc_io<TASK>::pwm_b_;
	template<class TASK>
	volatile uint16_t trc_io<TASK>::pwm_c_;
	template<class TASK>
	volatile uint16_t trc_io<TASK>::pwm_d_;

}
<|endoftext|>


<commit_before>#pragma once

#include <agency/detail/config.hpp>
#include <agency/detail/index_cast.hpp>
#include <agency/detail/shape_cast.hpp>
#include <agency/detail/utility.hpp>
#include <agency/detail/memory/allocator_traits.hpp>
#include <utility>
#include <memory>

namespace agency
{
namespace detail
{

template<class T, class Shape = size_t, class Alloc = std::allocator<T>, class Index = Shape>
class array
{
  public:
    using value_type = T;

    using allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<value_type>;

    using pointer = typename std::allocator_traits<allocator_type>::pointer;

    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;

    using shape_type = Shape;

    using index_type = Index;

    // note that array's constructors have __agency_hd_warning_disable__
    // because Alloc's constructors may not have __AGENCY_ANNOTATION

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array() : alloc_{}, shape_{}, data_(nullptr) {}

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    explicit array(const shape_type& shape, const allocator_type& alloc = allocator_type())
      : alloc_(allocator_type()),
        shape_(shape),
        data_(allocate_and_construct_elements(alloc_, size()))
    {
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    explicit array(const shape_type& shape, const T& val, const allocator_type& alloc = allocator_type())
      : alloc_(alloc),
        shape_(shape),
        data_(allocate_and_construct_elements(alloc_, size(), val))
    {
    }

    __agency_hd_warning_disable__
    template<class Iterator,
             class = typename std::enable_if<
               !std::is_convertible<Iterator,shape_type>::value
             >::type>
    __AGENCY_ANNOTATION
    array(Iterator first, Iterator last)
      : array(shape_cast<shape_type>(last - first))
    {
      for(auto result = begin(); result != end(); ++result, ++first)
      {
        *result = *first;
      }
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array(const array& other)
      : array(other.shape())
    {
      auto iter = other.begin();
      auto result = begin();

      for(; iter != other.end(); ++iter, ++result)
      {
        *result = *iter;
      }
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array(array&& other)
      : alloc_{}, shape_{}, data_{}
    {
      swap(other);
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    ~array()
    {
      clear();
    }

    __AGENCY_ANNOTATION
    array& operator=(const array& other)
    {
      // XXX this is not a very efficient implementation
      array tmp = other;
      swap(tmp);
      return *this;
    }

    __AGENCY_ANNOTATION
    array& operator=(array&& other)
    {
      swap(other);
      return *this;
    }

    __AGENCY_ANNOTATION
    void swap(array& other)
    {
      agency::detail::swap(shape_, other.shape_);
      agency::detail::swap(data_,  other.data_);
    }

    __AGENCY_ANNOTATION
    value_type& operator[](index_type idx)
    {
      std::size_t idx_1d = agency::detail::index_cast<std::size_t>(idx, shape(), size());

      return data_[idx_1d];
    }

    __AGENCY_ANNOTATION
    shape_type shape() const
    {
      return shape_;
    }

    __AGENCY_ANNOTATION
    std::size_t size() const
    {
      return agency::detail::shape_cast<std::size_t>(shape_);
    }

    __AGENCY_ANNOTATION
    pointer data()
    {
      return data_;
    }

    __AGENCY_ANNOTATION
    const_pointer data() const
    {
      return data_;
    }

    __AGENCY_ANNOTATION
    pointer begin()
    {
      return data();
    }

    __AGENCY_ANNOTATION
    pointer end()
    {
      return begin() + size();
    }

    __AGENCY_ANNOTATION
    const_pointer begin() const
    {
      return data();
    }

    __AGENCY_ANNOTATION
    const_pointer cbegin() const
    {
      return begin();
    }

    __AGENCY_ANNOTATION
    const_pointer end() const
    {
      return begin() + size();
    }

    __AGENCY_ANNOTATION
    const_pointer cend() const
    {
      return end();
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    void clear()
    {
      if(size())
      {
        // XXX should really destroy through the allocator
        for(auto& x : *this)
        {
          x.~value_type();
        }

        alloc_.deallocate(data_, size());

        shape_ = shape_type{};
      }
    }

    __agency_hd_warning_disable__
    template<class Range>
    __AGENCY_ANNOTATION
    bool operator==(const Range& rhs) const
    {
      auto i = begin();
      auto j = rhs.begin();

      for(; i != end(); ++i, ++j)
      {
        if(*i != *j)
        {
          return false;
        }
      }

      return true;
    }

  private:
    __agency_hd_warning_disable__
    template<class... Args>
    __AGENCY_ANNOTATION
    static pointer allocate_and_construct_elements(allocator_type& alloc, size_t size, Args&&... args)
    {
      pointer result = alloc.allocate(size);

      allocator_traits<allocator_type>::construct_each(alloc, result, result + size, std::forward<Args>(args)...);

      return result;
    }

    allocator_type alloc_;

    shape_type shape_;

    pointer data_;
};

} // end detail
} // end agency

<commit_msg>Add templated operator== friends for detail::array which allow the Range to be on either side of the ==<commit_after>#pragma once

#include <agency/detail/config.hpp>
#include <agency/detail/index_cast.hpp>
#include <agency/detail/shape_cast.hpp>
#include <agency/detail/utility.hpp>
#include <agency/detail/memory/allocator_traits.hpp>
#include <utility>
#include <memory>

namespace agency
{
namespace detail
{

template<class T, class Shape = size_t, class Alloc = std::allocator<T>, class Index = Shape>
class array
{
  public:
    using value_type = T;

    using allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<value_type>;

    using pointer = typename std::allocator_traits<allocator_type>::pointer;

    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;

    using shape_type = Shape;

    using index_type = Index;

    // note that array's constructors have __agency_hd_warning_disable__
    // because Alloc's constructors may not have __AGENCY_ANNOTATION

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array() : alloc_{}, shape_{}, data_(nullptr) {}

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    explicit array(const shape_type& shape, const allocator_type& alloc = allocator_type())
      : alloc_(allocator_type()),
        shape_(shape),
        data_(allocate_and_construct_elements(alloc_, size()))
    {
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    explicit array(const shape_type& shape, const T& val, const allocator_type& alloc = allocator_type())
      : alloc_(alloc),
        shape_(shape),
        data_(allocate_and_construct_elements(alloc_, size(), val))
    {
    }

    __agency_hd_warning_disable__
    template<class Iterator,
             class = typename std::enable_if<
               !std::is_convertible<Iterator,shape_type>::value
             >::type>
    __AGENCY_ANNOTATION
    array(Iterator first, Iterator last)
      : array(shape_cast<shape_type>(last - first))
    {
      for(auto result = begin(); result != end(); ++result, ++first)
      {
        *result = *first;
      }
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array(const array& other)
      : array(other.shape())
    {
      auto iter = other.begin();
      auto result = begin();

      for(; iter != other.end(); ++iter, ++result)
      {
        *result = *iter;
      }
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    array(array&& other)
      : alloc_{}, shape_{}, data_{}
    {
      swap(other);
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    ~array()
    {
      clear();
    }

    __AGENCY_ANNOTATION
    array& operator=(const array& other)
    {
      // XXX this is not a very efficient implementation
      array tmp = other;
      swap(tmp);
      return *this;
    }

    __AGENCY_ANNOTATION
    array& operator=(array&& other)
    {
      swap(other);
      return *this;
    }

    __AGENCY_ANNOTATION
    void swap(array& other)
    {
      agency::detail::swap(shape_, other.shape_);
      agency::detail::swap(data_,  other.data_);
    }

    __AGENCY_ANNOTATION
    value_type& operator[](index_type idx)
    {
      std::size_t idx_1d = agency::detail::index_cast<std::size_t>(idx, shape(), size());

      return data_[idx_1d];
    }

    __AGENCY_ANNOTATION
    shape_type shape() const
    {
      return shape_;
    }

    __AGENCY_ANNOTATION
    std::size_t size() const
    {
      return agency::detail::shape_cast<std::size_t>(shape_);
    }

    __AGENCY_ANNOTATION
    pointer data()
    {
      return data_;
    }

    __AGENCY_ANNOTATION
    const_pointer data() const
    {
      return data_;
    }

    __AGENCY_ANNOTATION
    pointer begin()
    {
      return data();
    }

    __AGENCY_ANNOTATION
    pointer end()
    {
      return begin() + size();
    }

    __AGENCY_ANNOTATION
    const_pointer begin() const
    {
      return data();
    }

    __AGENCY_ANNOTATION
    const_pointer cbegin() const
    {
      return begin();
    }

    __AGENCY_ANNOTATION
    const_pointer end() const
    {
      return begin() + size();
    }

    __AGENCY_ANNOTATION
    const_pointer cend() const
    {
      return end();
    }

    __agency_hd_warning_disable__
    __AGENCY_ANNOTATION
    void clear()
    {
      if(size())
      {
        // XXX should really destroy through the allocator
        for(auto& x : *this)
        {
          x.~value_type();
        }

        alloc_.deallocate(data_, size());

        shape_ = shape_type{};
      }
    }

    __agency_hd_warning_disable__
    template<class Range>
    __AGENCY_ANNOTATION
    friend bool operator==(const array& lhs, const Range& rhs)
    {
      auto i = lhs.begin();
      auto j = rhs.begin();

      for(; i != lhs.end(); ++i, ++j)
      {
        if(*i != *j)
        {
          return false;
        }
      }

      return true;
    }

    __agency_hd_warning_disable__
    template<class Range>
    __AGENCY_ANNOTATION
    friend bool operator==(const Range& lhs, const array& rhs)
    {
      return rhs == lhs;
    }

  private:
    __agency_hd_warning_disable__
    template<class... Args>
    __AGENCY_ANNOTATION
    static pointer allocate_and_construct_elements(allocator_type& alloc, size_t size, Args&&... args)
    {
      pointer result = alloc.allocate(size);

      allocator_traits<allocator_type>::construct_each(alloc, result, result + size, std::forward<Args>(args)...);

      return result;
    }

    allocator_type alloc_;

    shape_type shape_;

    pointer data_;
};

} // end detail
} // end agency

<|endoftext|>


<commit_before>#include <fstream>

#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <algorithm>

//using namespace std;

namespace configuration {

	template<typename Key = std::string>
	int last_of(const Key &key, const typename Key::value_type c) {
		auto it = std::find(key.rbegin(), key.rend(), c);
		return key.size() - std::distance(key.rbegin(), it);
	}

	template<typename Key = std::string>
	int next_of(const Key &key, int start, const typename Key::value_type c) {
		auto it = std::find(key.begin()+start, key.end(), c);
		return std::distance(key.begin(), it)-start;
	}

	template<typename Key = std::string, typename Value = std::string>
	struct config_holder {

		//using key = std::string;
		//using value = std::string;

		using key_iter = typename Key::const_iterator;
		using val_iter = typename Value::const_iterator;
		using key_pair = std::pair<key_iter, key_iter>;
		using val_pair = std::pair<val_iter, val_iter>;
		using range = std::pair<key_pair, val_pair>;
		using map_value = typename std::unordered_map<Key,Value>::value_type;

		auto add_item(key_iter kb, key_iter ke, val_iter vb, val_iter ve) -> void {
			_items.insert( make_pair(Key(kb, ke), Value(vb, ve)) );
		}

		auto get(const Key &key) const -> const Value & {
			auto it = _items.find(key);
			if( it == _items.end() )
				return _empty;
			return it->second;
		}

		auto prefix(const Key &prefix) const -> std::vector<map_value> {
			std::vector<map_value> values;
			std::for_each(begin(_items), end(_items), [&values, &prefix](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) )
					values.push_back(pair);
			});
			return values;
		}

		auto sufix(const Key &prefix) const -> std::unordered_set<Key> {
			std::unordered_set<Key> values;
			std::for_each(begin(_items), end(_items), [&values, &prefix](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) )
					values.insert( pair.first.substr( prefix.size() ) );
			});
			return values;
		}

		auto next_token(const Key &prefix, const typename Key::value_type separator) const -> std::unordered_set<Key> {
		//auto next_token(const Key &prefix, char separator) const -> std::unordered_set<Key> {
			std::unordered_set<Key> values;

			int pos = last_of(prefix, separator);

			std::for_each(begin(_items), end(_items), [&values, &prefix, &pos, &separator](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) ) {
					int npos = next_of(pair.first, pos, separator);
					values.insert( pair.first.substr( pos, npos ) );
				}
			});
			return values;
		}

	//private:
		std::unordered_map<Key, Value> _items;
		Value _empty;

	};

	void crack(const std::string &line, char delim,
		std::function<void(std::string::const_iterator, std::string::const_iterator, std::string::const_iterator)> f) {
		auto b = std::begin(line);
		auto e = std::end(line);
		auto pos = line.find(delim);
		if( pos != std::string::npos ) {
			f(b, b+pos, e);
		}
	}

	template<typename Key = std::string, typename Value = std::string>
	config_holder<Key, Value> load(const std::string &file_name) {

		using cfg = config_holder<Key, Value>;
		cfg config;

		std::ifstream istr;
		istr.open(file_name);

		using iter_type = std::string::const_iterator;
		std::function<void(iter_type, iter_type, iter_type)> f = [&config](iter_type b, iter_type m, iter_type e) {
			std::string k(b, m);
			std::string v(m+1, e);
			//b-m => key / m+1-e => value
			config.add_item( b, m, m+1, e );
		};

		while( istr.good() )  {
			std::string line;
			std::getline(istr, line);
			crack(line, '=', f);
		}

		for(auto item : config._items) {
			std::cout << "Item: [" << item.first << "] => [" << item.second << "]" << std::endl;
		}

		return config;

	}

}

int main() {

	std::string fname = "example.cfg";
	auto cfg = configuration::load(fname);

	const std::string &log_dir = cfg.get(std::string("log.base_dir"));
	auto plugins = cfg.prefix("plugin.");

	std::cout << log_dir << std::endl;

	for(auto p : plugins) {
		std::cout << p.first << "=>" << p.second << std::endl;
	}
	std::cout << "--------------" << std::endl;

	auto suf = cfg.sufix("plugin.socket");
	for(auto p : suf) {
		std::cout << p << std::endl;
	}
	std::cout << "--------------" << std::endl;

	auto tok = cfg.next_token("plugin.socket", '.');
	for(auto p : tok) {
		std::cout << p << std::endl;
	}

	const std::string &id = cfg.get(std::string("plugin.fix.id"));
	std::cout << "-> " << id << std::endl;

}<commit_msg>Pequenas mudanças - Antes de iterate_thru<commit_after>#include <fstream>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <algorithm>

namespace configuration {

	template<typename Key = std::string>
	int last_of(const Key &key, const typename Key::value_type c) {
		auto it = std::find(key.rbegin(), key.rend(), c);
		return key.size() - std::distance(key.rbegin(), it);
	}

	template<typename Key = std::string>
	int next_of(const Key &key, int start, const typename Key::value_type c) {
		auto it = std::find(key.begin()+start, key.end(), c);
		return std::distance(key.begin(), it)-start;
	}

	template<typename Key = std::string, typename Value = std::string>
	struct config_holder {

		using key_iter = typename Key::const_iterator;
		using val_iter = typename Value::const_iterator;
		using key_pair = std::pair<key_iter, key_iter>;
		using val_pair = std::pair<val_iter, val_iter>;
		using range = std::pair<key_pair, val_pair>;
		using config_map = std::unordered_map<Key, Value>;
		using map_value = typename std::unordered_map<Key,Value>::value_type;

		auto add_item(key_iter kb, key_iter ke, val_iter vb, val_iter ve) -> void {
			_items.insert( make_pair(Key(kb, ke), Value(vb, ve)) );
		}

		auto get(const Key &key) const -> const Value & {
			auto it = _items.find(key);
			if( it == _items.end() )
				return _empty;
			return it->second;
		}

		void iterate_thru() {}

		auto prefix(const Key &prefix) const -> std::vector<map_value> {
			std::vector<map_value> values;
			std::for_each(begin(_items), end(_items), [&values, &prefix](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) )
					values.push_back(pair);
			});
			return values;
		}

		auto sufix(const Key &prefix) const -> std::unordered_set<Key> {
			std::unordered_set<Key> values;
			std::for_each(begin(_items), end(_items), [&values, &prefix](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) )
					values.insert( pair.first.substr( prefix.size() ) );
			});
			return values;
		}

		auto next_token(const Key &prefix, const typename Key::value_type separator) const -> std::unordered_set<Key> {
			std::unordered_set<Key> values;
			int pos = last_of(prefix, separator);
			std::for_each(begin(_items), end(_items), [&values, &prefix, &pos, &separator](const std::pair<Key,Value> &pair) {
				//let's check prefix
				if( std::equal( begin(prefix), end(prefix), begin(pair.first) ) ) {
					int npos = next_of(pair.first, pos, separator);
					values.insert( pair.first.substr( pos, npos ) );
				}
			});
			return values;
		}

		auto items() const -> const std::unordered_map<Key, Value> & {
			return _items;
		}

	private:
		config_map _items;
		Value _empty;

	};

	template<typename AdderFunc>
	void crack(const std::string &line, char delim, AdderFunc f) {
		auto b = std::begin(line);
		auto e = std::end(line);
		auto pos = line.find(delim);
		if( pos != std::string::npos ) {
			f(b, b+pos, e);
		}
	}

	template<typename Key = std::string, typename Value = std::string>
	config_holder<Key, Value> load(const std::string &file_name) {

		using cfg = config_holder<Key, Value>;
		cfg config;

		std::ifstream istr;
		istr.open(file_name);

		using iter_type = std::string::const_iterator;
		std::function<void(iter_type, iter_type, iter_type)> f = [&config](iter_type b, iter_type m, iter_type e) {
			std::string k(b, m);
			std::string v(m+1, e);
			//b-m => key / m+1-e => value
			config.add_item( b, m, m+1, e );
		};

		while( istr.good() )  {
			std::string line;
			std::getline(istr, line);
			crack(line, '=', f);
		}

		for(auto item : config.items()) {
			std::cout << "Item: [" << item.first << "] => [" << item.second << "]" << std::endl;
		}

		return config;

	}

}

int main() {

	std::string fname = "example.cfg";
	auto cfg = configuration::load(fname);

	const std::string &log_dir = cfg.get(std::string("log.base_dir"));
	auto plugins = cfg.prefix("plugin.");

	std::cout << log_dir << std::endl;

	for(auto p : plugins) {
		std::cout << p.first << "=>" << p.second << std::endl;
	}
	std::cout << "--------------" << std::endl;

	auto suf = cfg.sufix("plugin.socket");
	for(auto p : suf) {
		std::cout << p << std::endl;
	}
	std::cout << "--------------" << std::endl;

	auto tok = cfg.next_token("plugin.socket", '.');
	for(auto p : tok) {
		std::cout << p << std::endl;
	}

	const std::string &id = cfg.get(std::string("plugin.fix.id"));
	std::cout << "-> " << id << std::endl;

}<|endoftext|>