<commit_before>/***********************************************************************
    filename:   ItemView.cpp
    created:    Sat May 24 2014
    author:     Timotei Dolean <timotei21@gmail.com>

    purpose:    Implementation of the base class for all item model-based views.
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include "CEGUI/views/ItemView.h"

namespace CEGUI
{

//----------------------------------------------------------------------------//
ViewRenderingState::ViewRenderingState() :
    d_isDirty(true)
{
}

//----------------------------------------------------------------------------//
ViewRenderingState::~ViewRenderingState()
{

}

//----------------------------------------------------------------------------//
ItemView::ItemView(const String& type, const String& name) :
    Window(type, name),
    d_itemModel(0),
    d_eventChildrenAddedConnection(0),
    d_eventChildrenRemovedConnection(0)
{
}

//----------------------------------------------------------------------------//
ItemView::~ItemView()
{
    disconnectModelEvents();
}

//----------------------------------------------------------------------------//
void ItemView::setModel(ItemModel* item_model)
{
    if (item_model == d_itemModel)
        return;

    if (d_itemModel != 0)
    {
        disconnectModelEvents();
    }

    d_itemModel = item_model;

    connectToModelEvents(d_itemModel);
    getRenderingState()->d_isDirty = true;
}

//----------------------------------------------------------------------------//
void ItemView::connectToModelEvents(ItemModel* d_itemModel)
{
    d_eventChildrenAddedConnection = d_itemModel->subscribeEvent(ItemModel::EventChildrenAdded,
        &ItemView::onChildrenAdded, this);
    d_eventChildrenRemovedConnection = d_itemModel->subscribeEvent(ItemModel::EventChildrenRemoved,
        &ItemView::onChildrenRemoved, this);
}

//----------------------------------------------------------------------------//
bool ItemView::onChildrenAdded(const EventArgs& args)
{
    getRenderingState()->d_isDirty = true;
    return true;
}

//----------------------------------------------------------------------------//
bool ItemView::onChildrenRemoved(const EventArgs& args)
{
    getRenderingState()->d_isDirty = true;
    return true;
}

//----------------------------------------------------------------------------//
void ItemView::disconnectModelEvents()
{
    if (d_eventChildrenAddedConnection != 0)
        d_eventChildrenAddedConnection->disconnect();

    if (d_eventChildrenRemovedConnection != 0)
        d_eventChildrenRemovedConnection->disconnect();
}
}
<commit_msg>Invalidate the view when model changed<commit_after>/***********************************************************************
    filename:   ItemView.cpp
    created:    Sat May 24 2014
    author:     Timotei Dolean <timotei21@gmail.com>

    purpose:    Implementation of the base class for all item model-based views.
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include "CEGUI/views/ItemView.h"

namespace CEGUI
{

//----------------------------------------------------------------------------//
ViewRenderingState::ViewRenderingState() :
    d_isDirty(true)
{
}

//----------------------------------------------------------------------------//
ViewRenderingState::~ViewRenderingState()
{

}

//----------------------------------------------------------------------------//
ItemView::ItemView(const String& type, const String& name) :
    Window(type, name),
    d_itemModel(0),
    d_eventChildrenAddedConnection(0),
    d_eventChildrenRemovedConnection(0)
{
}

//----------------------------------------------------------------------------//
ItemView::~ItemView()
{
    disconnectModelEvents();
}

//----------------------------------------------------------------------------//
void ItemView::setModel(ItemModel* item_model)
{
    if (item_model == d_itemModel)
        return;

    if (d_itemModel != 0)
    {
        disconnectModelEvents();
    }

    d_itemModel = item_model;

    connectToModelEvents(d_itemModel);
    getRenderingState()->d_isDirty = true;
}

//----------------------------------------------------------------------------//
void ItemView::connectToModelEvents(ItemModel* d_itemModel)
{
    d_eventChildrenAddedConnection = d_itemModel->subscribeEvent(ItemModel::EventChildrenAdded,
        &ItemView::onChildrenAdded, this);
    d_eventChildrenRemovedConnection = d_itemModel->subscribeEvent(ItemModel::EventChildrenRemoved,
        &ItemView::onChildrenRemoved, this);
}

//----------------------------------------------------------------------------//
bool ItemView::onChildrenAdded(const EventArgs& args)
{
    getRenderingState()->d_isDirty = true;
    invalidate(false);

    return true;
}

//----------------------------------------------------------------------------//
bool ItemView::onChildrenRemoved(const EventArgs& args)
{
    getRenderingState()->d_isDirty = true;
    invalidate(false);

    return true;
}

//----------------------------------------------------------------------------//
void ItemView::disconnectModelEvents()
{
    if (d_eventChildrenAddedConnection != 0)
        d_eventChildrenAddedConnection->disconnect();

    if (d_eventChildrenRemovedConnection != 0)
        d_eventChildrenRemovedConnection->disconnect();
}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include <iostream>
#include "gmxtopologyreader.h"

#if GMX == 50
        #include <gromacs/legacyheaders/statutil.h>
        #include <gromacs/legacyheaders/typedefs.h>
        #include <gromacs/legacyheaders/smalloc.h>
        #include <gromacs/legacyheaders/vec.h>
        #include <gromacs/legacyheaders/copyrite.h>
        #include <gromacs/legacyheaders/statutil.h>
        #include <gromacs/fileio/tpxio.h>
#elif GMX == 45
        #include <gromacs/statutil.h>
        #include <gromacs/typedefs.h>
        #include <gromacs/smalloc.h>
        #include <gromacs/vec.h>
        #include <gromacs/copyrite.h>
        #include <gromacs/statutil.h>
        #include <gromacs/tpxio.h>
#elif GMX == 40
    extern "C"
    {
        #include <statutil.h>
        #include <typedefs.h>
        #include <smalloc.h>
        #include <vec.h>
        #include <copyrite.h>
        #include <statutil.h>
        #include <tpxio.h>
    }
#else
#error Unsupported GMX version
#endif
    // this one is needed because of bool is defined in one of the headers included by gmx
    #undef bool

namespace votca { namespace csg {

bool GMXTopologyReader::ReadTopology(string file, Topology &top)
{
    gmx_mtop_t mtop;

    int natoms;
    // cleanup topology to store new data
    top.Cleanup();

#if GMX == 50
    t_inputrec ir;
    ::matrix gbox;

    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,NULL,&mtop);
#elif GMX == 45
    set_program_name("VOTCA");

    t_inputrec ir;
    ::matrix gbox;
    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,NULL,&mtop);
#elif GMX == 40
    set_program_name("VOTCA");

    int sss;   // wtf is this
    ::real    ttt,lll; // wtf is this
    (void)read_tpx((char *)file.c_str(),&sss,&ttt,&lll,NULL,NULL,&natoms,NULL,NULL,NULL,&mtop);
#else
#error Unsupported GMX version
#endif

    int count=0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock)
        count+=mtop.molblock[iblock].nmol;

    if(count != mtop.mols.nr  ) {
        throw runtime_error("gromacs topology contains inconsistency in molecule definitons\n\n"
                "A possible reason is an outdated .tpr file. Please rerun grompp to generate a new tpr file.\n"
                "If the problem remains or "
                "you're missing the files to rerun grompp,\n contact the votca mailing list for a solution.");
    }

    for(int iblock=0; iblock<mtop.nmolblock; ++iblock) {
        gmx_moltype_t *mol
                = &(mtop.moltype[mtop.molblock[iblock].type]);

        string molname =  *(mol->name);

        int res_offset = top.ResidueCount();

        t_atoms *atoms=&(mol->atoms);

        for(int i=0; i < atoms->nres; i++) {
#if GMX == 50
                top.CreateResidue(*(atoms->resinfo[i].name));
#elif GMX == 45
                top.CreateResidue(*(atoms->resinfo[i].name));
#elif GMX == 40
                top.CreateResidue(*(atoms->resname[i]));
#else
#error Unsupported GMX version
#endif
        }

        int ifirstatom = 0;
        for(int imol=0; imol<mtop.molblock[iblock].nmol; ++imol) {
            Molecule *mi = top.CreateMolecule(molname);

            // read the atoms
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                t_atom *a = &(atoms->atom[iatom]);

                // read exclusions
                t_blocka * excl = &(mol->excls);
                // insert exclusions
                list<int> excl_list;
                for(int k=excl->index[iatom]; k<excl->index[iatom+1]; k++) {
                    excl_list.push_back(excl->a[k]+ifirstatom);
                }
                top.InsertExclusion(iatom+ifirstatom, excl_list);

                BeadType *type = top.GetOrCreateBeadType(*(atoms->atomtype[iatom]));
#if GMX == 50
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind, a->m, a->q);
#elif GMX == 45
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind, a->m, a->q);
#elif GMX == 40
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resnr, a->m, a->q);
#else
#error Unsupported GMX version
#endif

                stringstream nm;
                nm << bead->getResnr() + 1 << ":" <<  top.getResidue(res_offset + bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }
            ifirstatom+=mtop.molblock[iblock].natoms_mol;
        }
    }

    return true;
}

}}
<commit_msg>gmxtopologyreader: changes for gromacs 5.0-beta2<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include <iostream>
#include "gmxtopologyreader.h"

#if GMX == 50
        #include <gromacs/fileio/tpxio.h>
#elif GMX == 45
        #include <gromacs/statutil.h>
        #include <gromacs/typedefs.h>
        #include <gromacs/smalloc.h>
        #include <gromacs/vec.h>
        #include <gromacs/copyrite.h>
        #include <gromacs/statutil.h>
        #include <gromacs/tpxio.h>
#elif GMX == 40
    extern "C"
    {
        #include <statutil.h>
        #include <typedefs.h>
        #include <smalloc.h>
        #include <vec.h>
        #include <copyrite.h>
        #include <statutil.h>
        #include <tpxio.h>
    }
#else
#error Unsupported GMX version
#endif
    // this one is needed because of bool is defined in one of the headers included by gmx
    #undef bool

namespace votca { namespace csg {

bool GMXTopologyReader::ReadTopology(string file, Topology &top)
{
    gmx_mtop_t mtop;

    int natoms;
    // cleanup topology to store new data
    top.Cleanup();

#if GMX == 50
    t_inputrec ir;
    ::matrix gbox;

    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,NULL,&mtop);
#elif GMX == 45
    set_program_name("VOTCA");

    t_inputrec ir;
    ::matrix gbox;
    (void)read_tpx((char *)file.c_str(),&ir,gbox,&natoms,NULL,NULL,NULL,&mtop);
#elif GMX == 40
    set_program_name("VOTCA");

    int sss;   // wtf is this
    ::real    ttt,lll; // wtf is this
    (void)read_tpx((char *)file.c_str(),&sss,&ttt,&lll,NULL,NULL,&natoms,NULL,NULL,NULL,&mtop);
#else
#error Unsupported GMX version
#endif

    int count=0;
    for(int iblock=0; iblock<mtop.nmolblock; ++iblock)
        count+=mtop.molblock[iblock].nmol;

    if(count != mtop.mols.nr  ) {
        throw runtime_error("gromacs topology contains inconsistency in molecule definitons\n\n"
                "A possible reason is an outdated .tpr file. Please rerun grompp to generate a new tpr file.\n"
                "If the problem remains or "
                "you're missing the files to rerun grompp,\n contact the votca mailing list for a solution.");
    }

    for(int iblock=0; iblock<mtop.nmolblock; ++iblock) {
        gmx_moltype_t *mol
                = &(mtop.moltype[mtop.molblock[iblock].type]);

        string molname =  *(mol->name);

        int res_offset = top.ResidueCount();

        t_atoms *atoms=&(mol->atoms);

        for(int i=0; i < atoms->nres; i++) {
#if GMX == 50
                top.CreateResidue(*(atoms->resinfo[i].name));
#elif GMX == 45
                top.CreateResidue(*(atoms->resinfo[i].name));
#elif GMX == 40
                top.CreateResidue(*(atoms->resname[i]));
#else
#error Unsupported GMX version
#endif
        }

        int ifirstatom = 0;
        for(int imol=0; imol<mtop.molblock[iblock].nmol; ++imol) {
            Molecule *mi = top.CreateMolecule(molname);

            // read the atoms
            for(int iatom=0; iatom<mtop.molblock[iblock].natoms_mol; iatom++) {
                t_atom *a = &(atoms->atom[iatom]);

                // read exclusions
                t_blocka * excl = &(mol->excls);
                // insert exclusions
                list<int> excl_list;
                for(int k=excl->index[iatom]; k<excl->index[iatom+1]; k++) {
                    excl_list.push_back(excl->a[k]+ifirstatom);
                }
                top.InsertExclusion(iatom+ifirstatom, excl_list);

                BeadType *type = top.GetOrCreateBeadType(*(atoms->atomtype[iatom]));
#if GMX == 50
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind, a->m, a->q);
#elif GMX == 45
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resind, a->m, a->q);
#elif GMX == 40
                Bead *bead = top.CreateBead(1, *(atoms->atomname[iatom]), type, a->resnr, a->m, a->q);
#else
#error Unsupported GMX version
#endif

                stringstream nm;
                nm << bead->getResnr() + 1 << ":" <<  top.getResidue(res_offset + bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }
            ifirstatom+=mtop.molblock[iblock].natoms_mol;
        }
    }

    return true;
}

}}
<|endoftext|>


<commit_before>#ifndef INCLUDED_SROOK_IOS_BIFSTREAM_HPP
#define INCLUDED_SROOK_IOS_BIFSTREAM_HPP
#include<srook/config/noexcept_detection.hpp>
#include<srook/cstddef/byte.hpp>
#include<srook/config/require.hpp>
#include<srook/type_traits/is_callable.hpp>

#include<fstream>
#include<type_traits>
#include<array>
#include<memory>
#include<algorithm>

namespace srook{
inline namespace v1{

struct bifstream final : std::ifstream {
	using std::ifstream::ifstream;

	explicit bifstream(const char* filename,const std::ios_base::openmode& open_mode = std::ios::in | std::ios::binary)
		:std::ifstream{},
		buffer{},
		last(nullptr),
		forward_iter(nullptr)
	{
		try{
			exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
			open(filename,open_mode);
			seekg(0,std::fstream::end);
			const std::size_t end_pos = std::size_t(tellg());
			clear();
			seekg(0,std::fstream::beg);
			const std::size_t begin_pos = std::size_t(tellg());
			const std::size_t size = end_pos - begin_pos;

			buffer = std::make_unique<srook::byte[]>(size);

			exceptions(std::ios::badbit);
			read(reinterpret_cast<char*>(buffer.get()),long(size));
			close();

			forward_iter = buffer.get();
			last = buffer.get() + size;
		}catch(const std::ios_base::failure& e){
			buffer.reset();
			nextflag = readflag = false;
			last = forward_iter = nullptr;
			bit_position = -1;
		}
	}

	void skip_byte(std::size_t n)
	{
		if(forward_iter + n > last)throw std::out_of_range(__func__);
		if((forward_iter += n) >= last)readflag = false;
		bit_position = 7;
	}

	explicit operator bool()const noexcept
	{
		return readflag;
	}

	std::size_t size()const noexcept
	{
		return last - buffer.get();
	}

	srook::byte* next_address()const noexcept
	{
		if(bit_position == 7)return forward_iter;
		else if(forward_iter < last)return forward_iter + 1;
		else return nullptr;
	}
private:
	struct tag_argument{
		explicit constexpr tag_argument(int num):n(std::move(num)){}
		int n;
	};
public:
	static constexpr auto Byte = []{};
	static constexpr auto Word = []{};
	static constexpr auto Bytes = []{};

	struct Byte_n : tag_argument{
		using tag_argument::tag_argument;
	};
	struct Bits : tag_argument{
		using tag_argument::tag_argument;
	};
private:
	std::unique_ptr<srook::byte[]> buffer;
	srook::byte* last;
	srook::byte* forward_iter;

	int bit_position = 7u;
	const std::array<srook::byte,8> bit_fullmask {
		{ srook::byte(0x01),srook::byte(0x02),srook::byte(0x04),srook::byte(0x08),srook::byte(0x10),srook::byte(0x20),srook::byte(0x40),srook::byte(0x80) }
	};
	bool nextflag = true;
	bool readflag = true;
private:
	void increment_buffer()noexcept
	{
		if(++forward_iter >= last){
			readflag = false;
		}
	}

	template<class T,std::size_t v>
	friend std::pair<const decltype(Bytes)&,bifstream&>
	operator>>(std::pair<const decltype(Bytes)&,bifstream&> p,const std::array<T,v>& ar)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(this_.bit_position != 7){
			this_.increment_buffer();
			this_.bit_position = 7;
		}
		if(this_.forward_iter + ar.size() > this_.last)throw std::out_of_range(__func__);
		std::copy(this_.forward_iter,this_.forward_iter + ar.size(),std::begin(ar));
		if((this_.forward_iter += ar.size()) >= this_.last)this_.readflag = false;

		return p;
	}

	template<class Value,REQUIRES(!srook::is_callable_v<std::decay_t<Value>>)>
	friend std::pair<const decltype(Byte)&,bifstream&>
   	operator>>(std::pair<const decltype(Byte)&,bifstream&> p,Value& src)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(this_.readflag){
			if(this_.bit_position != 7){
				this_.increment_buffer();
				this_.bit_position = 7;
			}
			src = Value(*this_.forward_iter);
			this_.increment_buffer();
			this_.nextflag = true;
		}else{
			throw std::runtime_error(__func__);
		}

		return p;
	}

	template<class T,REQUIRES(std::is_integral<std::decay_t<T>>::value)>
	friend std::pair<const decltype(Word)&,bifstream&>
	operator>>(std::pair<const decltype(Word)&,bifstream&> p,T& value)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(this_.readflag){
			if(this_.bit_position != 7){
				this_.increment_buffer();
				this_.bit_position = 7;
			}
			value = srook::to_integer<T>(*this_.forward_iter << 8);
			this_.increment_buffer();
			value |= srook::to_integer<T>(*this_.forward_iter);
			this_.increment_buffer();
		}else{
			throw std::runtime_error(__func__);
		}
		return p;
	}

	template<class T>
	friend std::pair<Bits,bifstream&>
	operator>>(std::pair<Bits,bifstream&> p,T& value)noexcept(false)
	{
		using namespace srook::literals::byte_literals;

		if(p.first.n <= 0)throw std::invalid_argument(__func__);
		bifstream& this_ = p.second;

		srook::byte r = 0_byte;
		for(srook::byte c = 0_byte; p.first.n; --p.first.n){
			if(this_.bit_position < 0){
				this_.bit_position = 7;
				this_.increment_buffer();
				if(!this_.nextflag){
					this_.increment_buffer();
					this_.nextflag = true;
				}
				c = *this_.forward_iter;
				if(c == 0xff_byte){
					c = *(this_.forward_iter + 1);
					if(srook::to_integer<bool>(c)){
						throw std::runtime_error(__func__);
					}
					this_.readflag = false;
				}
			}
			r <<= 1;
			r |= srook::to_integer<bool>(((*this_.forward_iter) & this_.bit_fullmask[std::size_t(this_.bit_position--)])) ? 1_byte : 0_byte;
		}
		value = T(r);

		return p;
	}

	template<class Range>
	friend std::pair<const Byte_n&,bifstream&>
	operator>>(std::pair<const Byte_n&,bifstream&> p,Range& r)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(this_.bit_position != 7){
			this_.increment_buffer();
			this_.bit_position = 7;
		}
		if(this_.forward_iter + p.first.n > this_.last)throw std::out_of_range(__func__);

		if(r.size() >= std::size_t(p.first.n)){
			std::generate(std::begin(r),std::end(r),[&this_]{return typename Range::value_type(*this_.forward_iter++);});
		}else{
			r.resize(std::size_t(p.first.n));
			std::generate(std::begin(r),std::end(r),[&this_]{return typename Range::value_type(*this_.forward_iter++);});
		}

		if(this_.forward_iter >= this_.last)this_.readflag = false;

		return p;
	}

	template<class Tag>
	constexpr friend std::pair<Tag,bifstream&> operator|(bifstream& ofps,const Tag& t)
	{
		return std::make_pair(t,std::ref(ofps));
	}

	friend std::pair<Bits,bifstream&> operator|(bifstream& ofps,const Bits& bits)
	{
		return std::make_pair(bits,std::ref(ofps));
	}
};

} // inline namespace v1
} // namespace srook
#endif
<commit_msg>small fix<commit_after>#ifndef INCLUDED_SROOK_IOS_BIFSTREAM_HPP
#define INCLUDED_SROOK_IOS_BIFSTREAM_HPP
#include<srook/config/noexcept_detection.hpp>
#include<srook/cstddef/byte.hpp>
#include<srook/config/require.hpp>
#include<srook/type_traits/is_callable.hpp>
#include<srook/optional.hpp>
#include<fstream>
#include<type_traits>
#include<array>
#include<memory>
#include<algorithm>

namespace srook{
inline namespace v1{

struct bifstream final : std::ifstream {
	using std::ifstream::ifstream;

	explicit bifstream(const char* filename,const std::ios_base::openmode& open_mode = std::ios::in | std::ios::binary)
		:std::ifstream{},
		buffer{},
		last(nullptr),
		forward_iter(nullptr)
	{
		try{
			exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
			open(filename,open_mode);
			seekg(0,std::fstream::end);
			const std::size_t end_pos = std::size_t(tellg());
			clear();
			seekg(0,std::fstream::beg);
			const std::size_t begin_pos = std::size_t(tellg());
			const std::size_t size = end_pos - begin_pos;

			buffer = std::make_unique<srook::byte[]>(size);

			exceptions(std::ios::badbit);
			read(reinterpret_cast<char*>(buffer.get()),long(size));
			close();

			forward_iter = buffer.get();
			last = std::next(buffer.get(),size);
		}catch(const std::ios_base::failure& e){
			buffer.reset();
			nextflag = readflag = false;
			last = forward_iter = nullptr;
			bit_position = srook::nullopt;
		}
	}

	void skip_byte(std::size_t n)
	{
		if(forward_iter + n > last)throw std::out_of_range(__func__);
		if((forward_iter += n) >= last)readflag = false;
		bit_position = 7;
	}

	explicit operator bool()const noexcept
	{
		return readflag;
	}

	std::size_t size()const noexcept
	{
		return last - buffer.get();
	}

	srook::byte* next_address()const noexcept
	{
		if(!bit_position)return nullptr;
		else if(bit_position.value() == 7)return forward_iter;
		else if(forward_iter < last)return forward_iter + 1;
		else return nullptr;
	}
private:
	struct tag_argument{
		explicit constexpr tag_argument(int num):n(std::move(num)){}
		int n;
	};
public:
	static constexpr auto Byte = []{};
	static constexpr auto Word = []{};
	static constexpr auto Bytes = []{};

	struct Byte_n : tag_argument{
		using tag_argument::tag_argument;
	};
	struct Bits : tag_argument{
		using tag_argument::tag_argument;
	};
private:
	std::unique_ptr<srook::byte[]> buffer;
	srook::byte* last;
	srook::byte* forward_iter;

	srook::optional<int> bit_position = 7u;
	const std::array<srook::byte,8> bit_fullmask {
		{ srook::byte(0x01),srook::byte(0x02),srook::byte(0x04),srook::byte(0x08),srook::byte(0x10),srook::byte(0x20),srook::byte(0x40),srook::byte(0x80) }
	};
	bool nextflag = true;
	bool readflag = true;
private:
	void increment_buffer()noexcept
	{
		if(++forward_iter >= last){
			readflag = false;
		}
	}

	template<class T,std::size_t v>
	friend std::pair<const decltype(Bytes)&,bifstream&>
	operator>>(std::pair<const decltype(Bytes)&,bifstream&> p,const std::array<T,v>& ar)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(!this_.bit_position)throw std::runtime_error("invalid construct");

		if(this_.bit_position.value() != 7){
			this_.increment_buffer();
			this_.bit_position = 7;
		}
		if(this_.forward_iter + ar.size() > this_.last)throw std::out_of_range(__func__);
		std::copy(this_.forward_iter,this_.forward_iter + ar.size(),std::begin(ar));
		if((this_.forward_iter += ar.size()) >= this_.last)this_.readflag = false;

		return p;
	}

	template<class Value,REQUIRES(!srook::is_callable_v<std::decay_t<Value>>)>
	friend std::pair<const decltype(Byte)&,bifstream&>
   	operator>>(std::pair<const decltype(Byte)&,bifstream&> p,Value& src)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(!this_.bit_position)throw std::runtime_error("invalid construct");

		if(this_.readflag){
			if(this_.bit_position.value() != 7){
				this_.increment_buffer();
				this_.bit_position = 7;
			}
			src = Value(*this_.forward_iter);
			this_.increment_buffer();
			this_.nextflag = true;
		}else{
			throw std::runtime_error(__func__);
		}

		return p;
	}

	template<class T,REQUIRES(std::is_integral<std::decay_t<T>>::value)>
	friend std::pair<const decltype(Word)&,bifstream&>
	operator>>(std::pair<const decltype(Word)&,bifstream&> p,T& value)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(!this_.bit_position)throw std::runtime_error("invalid construct");

		if(this_.readflag){
			if(this_.bit_position.value() != 7){
				this_.increment_buffer();
				this_.bit_position = 7;
			}
			value = srook::to_integer<T>(*this_.forward_iter << 8);
			this_.increment_buffer();
			value |= srook::to_integer<T>(*this_.forward_iter);
			this_.increment_buffer();
		}else{
			throw std::runtime_error(__func__);
		}
		return p;
	}

	template<class T>
	friend std::pair<Bits,bifstream&>
	operator>>(std::pair<Bits,bifstream&> p,T& value)noexcept(false)
	{
		using namespace srook::literals::byte_literals;

		if(p.first.n <= 0)throw std::invalid_argument(__func__);

		bifstream& this_ = p.second;
		if(!this_.bit_position) throw std::runtime_error("invalid construct");

		srook::byte r = 0_byte;
		for(srook::byte c = 0_byte; p.first.n; --p.first.n){
			if(this_.bit_position.value() < 0){
				this_.bit_position = 7;
				this_.increment_buffer();
				if(!this_.nextflag){
					this_.increment_buffer();
					this_.nextflag = true;
				}
				c = *this_.forward_iter;
				if(c == 0xff_byte){
					c = *(this_.forward_iter + 1);
					if(srook::to_integer<bool>(c)){
						throw std::runtime_error(__func__);
					}
					this_.readflag = false;
				}
			}
			r <<= 1;
			r |= srook::to_integer<bool>(((*this_.forward_iter) & this_.bit_fullmask[std::size_t(this_.bit_position.value())])) ? 1_byte : 0_byte;
			this_.bit_position = this_.bit_position.value() - 1;
		}
		value = T(r);

		return p;
	}

	template<class Range>
	friend std::pair<const Byte_n&,bifstream&>
	operator>>(std::pair<const Byte_n&,bifstream&> p,Range& r)noexcept(false)
	{
		bifstream& this_ = p.second;

		if(this_.bit_position != 7){
			this_.increment_buffer();
			this_.bit_position = 7;
		}
		if(this_.forward_iter + p.first.n > this_.last)throw std::out_of_range(__func__);

		if(r.size() >= std::size_t(p.first.n)){
			std::generate(std::begin(r),std::end(r),[&this_]{return typename Range::value_type(*this_.forward_iter++);});
		}else{
			r.resize(std::size_t(p.first.n));
			std::generate(std::begin(r),std::end(r),[&this_]{return typename Range::value_type(*this_.forward_iter++);});
		}

		if(this_.forward_iter >= this_.last)this_.readflag = false;

		return p;
	}

	template<class Tag>
	constexpr friend std::pair<Tag,bifstream&> operator|(bifstream& ofps,const Tag& t)
	{
		return std::make_pair(t,std::ref(ofps));
	}

	friend std::pair<Bits,bifstream&> operator|(bifstream& ofps,const Bits& bits)
	{
		return std::make_pair(bits,std::ref(ofps));
	}
};

} // inline namespace v1
} // namespace srook
#endif
<|endoftext|>


<commit_before>#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/AST.h"
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/Support/raw_ostream.h"
#include "NodeTyper.h"
#include "TyperVisitor.h"
#include "llvm/Support/Debug.h"
#include <iostream>

// Random numbers unlikely to come up in source programs...
#define TAG_ENDORSEMENT 9946037276205

using namespace clang;

namespace {

// The types in the EnerC type system.
const uint32_t ecPrecise = 0;
const uint32_t ecApprox = 1;

// The typer: assign types to AST nodes.
class EnerCTyper : public NodeTyper {
public:
  virtual uint32_t typeForQualString(llvm::StringRef s);
  virtual uint32_t defaultType(clang::Decl *decl);
  virtual uint32_t typeForExpr(clang::Expr *expr);
  virtual void checkStmt(clang::Stmt *stmt);
  virtual QualType withQuals(QualType oldT, uint32_t type);
  bool compatible(uint32_t lhs, uint32_t rhs);
  bool compatible(clang::QualType lhs, clang::QualType rhs);
  bool qualsEqual(clang::QualType lhs, clang::QualType rhs);
  void assertFlow(clang::QualType type, clang::Expr *expr);

  EnerCTyper(TyperConsumer *_controller) :
    NodeTyper(_controller) {}

private:
  void checkCondition(clang::Expr *cond);
};

// Plugin hooks for Clang driver.
class EnerCTypeCheckerAction: public PluginASTAction {
protected:
  ASTConsumer *CreateASTConsumer( CompilerInstance &CI, llvm::StringRef ) {
    // Pass the type-checking visitor back to Clang so we get called to
    // traverse all ASTs.
    return new TyperVisitor<EnerCTyper>( CI );
  }

  bool ParseArgs( const CompilerInstance &CI,
                  const std::vector<std::string>& args ) {
    // No arguments.
    return true;
  }

  void PrintHelp( llvm::raw_ostream& ros ) {
    ros << "TODO\n";
  }

  virtual ~EnerCTypeCheckerAction() {
  }
};

} // end namespace

// Register the plugin.
static FrontendPluginRegistry::Add<EnerCTypeCheckerAction> X(
    "enerc-type-checker", "perform EnerC type checking" );

// Assign qualifiers to declarations based on type annotations.
uint32_t EnerCTyper::typeForQualString(llvm::StringRef s) {
  if (s.equals("approx")) {
    return ecApprox;
  } else if (s.equals("precise")) {
    return ecPrecise;
  } else {
    std::cerr << "INVALID QUALIFIER: " << s.str() << "\n";
    return ecPrecise;
  }
}

// Default type for unannotated declarations.
uint32_t EnerCTyper::defaultType(clang::Decl *decl) {
  return ecPrecise;
}

// Type compatibility: the information flow rule.
bool EnerCTyper::compatible(uint32_t lhs, uint32_t rhs) {
  if (lhs == ecPrecise) {
    if (rhs == ecPrecise)
      return true;
    else
      return false;
  } else {
    return true;
  }
}

bool EnerCTyper::compatible(clang::QualType lhs, clang::QualType rhs) {
  if (lhs.isNull() || rhs.isNull())
    return true;

  // Current type level.
  if (!compatible(lhs.getQualifiers().getCustomQuals(),
                  rhs.getQualifiers().getCustomQuals())) {
    return false;
  }

  // Possibly recuse into referent types. After the first level, all
  // qualifiers must be *equal*. This incompatibility prevents unsoundness
  // that arises when different types alias.
  if (controller->ci.getASTContext().UnwrapSimilarPointerTypes(lhs, rhs)) {
    return qualsEqual(lhs, rhs);
  } else {
    return true;
  }
}

bool EnerCTyper::qualsEqual(clang::QualType lhs, clang::QualType rhs) {
  if (lhs.isNull() || rhs.isNull())
    return true;
  if (lhs.getQualifiers().getCustomQuals() !=
      rhs.getQualifiers().getCustomQuals()) {
    return false;
  }
  if (controller->ci.getASTContext().UnwrapSimilarPointerTypes(lhs, rhs)) {
    return qualsEqual(lhs, rhs);
  } else {
    return true;
  }
}

void EnerCTyper::assertFlow(clang::QualType type, clang::Expr *expr) {
  // Special-case malloc on the RHS.
  clang::Expr *innerExpr = expr->IgnoreImplicit();
  if (clang::CastExpr *castExpr = llvm::dyn_cast<clang::CastExpr>(innerExpr)) {
    innerExpr = castExpr->getSubExpr();
    innerExpr = innerExpr->IgnoreImplicit();
  }
  if (clang::CallExpr *callExpr = llvm::dyn_cast<clang::CallExpr>(innerExpr))
    if (clang::FunctionDecl *fdecl = callExpr->getDirectCallee())
      if (fdecl->getNameAsString() == "malloc")
        return;

  // Other cases.
  assertCompatible(type, expr, "precision flow violation");
}

// Give types to expressions.
uint32_t EnerCTyper::typeForExpr(clang::Expr *expr) {
  // Tolerate null.
  if (!expr)
    return ecPrecise;

  switch ( expr->getStmtClass() ) {

  // LITERALS
  case clang::Stmt::CharacterLiteralClass:
  case clang::Stmt::IntegerLiteralClass:
  case clang::Stmt::StringLiteralClass:
  case clang::Stmt::ImaginaryLiteralClass:
  case clang::Stmt::CompoundLiteralExprClass:
  case clang::Stmt::CXXBoolLiteralExprClass:
  case clang::Stmt::CXXNullPtrLiteralExprClass:
  case clang::Stmt::GNUNullExprClass:
  case clang::Stmt::FloatingLiteralClass:
  case clang::Stmt::UnaryTypeTraitExprClass:
  case clang::Stmt::CXXConstructExprClass:
  case clang::Stmt::CXXNewExprClass:
  case clang::Stmt::CXXDeleteExprClass:
  case clang::Stmt::OffsetOfExprClass:
  case clang::Stmt::SizeOfPackExprClass:
    return ecPrecise;

  // VARIABLE REFERENCES
//  case clang::Stmt::BlockDeclRefExprClass: {
//    clang::BlockDeclRefExpr* tex = cast<clang::BlockDeclRefExpr>(expr);
//    return typeOf(tex->getDecl());
//  }
  case clang::Stmt::DeclRefExprClass:
    return CL_LEAVE_UNCHANGED;
  case clang::Stmt::DependentScopeDeclRefExprClass: {
    DEBUG(llvm::errs() << "UNSOUND: template argument untypable\n");
    return ecPrecise;
  }
  case clang::Stmt::MemberExprClass:
    return CL_LEAVE_UNCHANGED;

  // CASTS
  // In all cases, we just propagate the qualifier of the casted expression.
  // This is especially important for implicit casts, but for explicit casts we
  // might eventually want to allow qualifiers -- but that should probably only
  // be done with endorsements.
  case clang::Stmt::ImplicitCastExprClass:
    return CL_LEAVE_UNCHANGED;

  case clang::Stmt::CStyleCastExprClass:
  case clang::Stmt::CXXFunctionalCastExprClass:
  case clang::Stmt::CXXConstCastExprClass:
  case clang::Stmt::CXXDynamicCastExprClass:
  case clang::Stmt::CXXReinterpretCastExprClass:
  case clang::Stmt::CXXStaticCastExprClass:
    return typeOf(cast<clang::CastExpr>(expr)->getSubExpr());

  // BINARY OPERATORS
  case clang::Stmt::BinaryOperatorClass: {
    clang::BinaryOperator *bop = llvm::cast<BinaryOperator>(expr);
    DEBUG(llvm::errs() << "binary operator " << bop->getOpcode() << "\n");
    DEBUG(bop->getLHS()->dump());
    DEBUG(bop->getRHS()->dump());
    uint32_t ltype = typeOf(bop->getLHS());
    uint32_t rtype = typeOf(bop->getRHS());

    DEBUG(llvm::errs() << "left " << ltype << " right " << rtype << "\n");

    switch (bop->getOpcode()) {
      case BO_Mul:
      case BO_Div:
      case BO_Rem:
      case BO_Add:
      case BO_Sub:
      case BO_Shl:
      case BO_Shr:
      case BO_LT:
      case BO_GT:
      case BO_LE:
      case BO_GE:
      case BO_EQ:
      case BO_NE:
      case BO_And:
      case BO_Xor:
      case BO_Or:
      case BO_LAnd:
      case BO_LOr:
        DEBUG(llvm::errs() << "arithmetic\n");
        if (ltype == ecApprox || rtype == ecApprox)
          return ecApprox;
        else
          return ecPrecise;

      case BO_Assign:
      case BO_MulAssign:
      case BO_DivAssign:
      case BO_RemAssign:
      case BO_AddAssign:
      case BO_SubAssign:
      case BO_ShlAssign:
      case BO_ShrAssign:
      case BO_AndAssign:
      case BO_XorAssign:
      case BO_OrAssign:
        DEBUG(llvm::errs() << "assignment\n");
        assertFlow(bop->getLHS()->getType(), bop->getRHS());
        return ltype;

      case BO_Comma:
        {
          // Endorsements are encoded as comma expressions!
          clang::IntegerLiteral *literal =
              dyn_cast<clang::IntegerLiteral>(bop->getLHS());
          if (literal && literal->getValue() == TAG_ENDORSEMENT) {
            // This is an endorsement of the right-hand expression.
            return ecPrecise;
          } else {
            // An ordinary comma expression.
            return CL_LEAVE_UNCHANGED;
          }
        }

      case BO_PtrMemD:
      case BO_PtrMemI:
        DEBUG(llvm::errs() << "UNSOUND: unimplemented: pointer-to-mem\n");
        return ecPrecise;
    }
  }

  // UNARY OPERATORS
  case clang::Stmt::UnaryOperatorClass: {
    clang::UnaryOperator *uop = llvm::cast<UnaryOperator>(expr);
    uint32_t argt = typeOf(uop->getSubExpr());
    switch (uop->getOpcode()) {
      case UO_PostInc:
      case UO_PostDec:
      case UO_PreInc:
      case UO_PreDec:
      case UO_Plus:
      case UO_Minus:
      case UO_Not:
      case UO_LNot:
        // arithmetic
        return argt;

      case UO_AddrOf:
      case UO_Deref:
        return CL_LEAVE_UNCHANGED;

      case UO_Real:
      case UO_Imag:
      case UO_Extension:
        // funky complex stuff
        return argt;
    }
  }

  // ARRAYS
  case clang::Stmt::ArraySubscriptExprClass:
    return CL_LEAVE_UNCHANGED;

  // FUNCTION CALLS
  case clang::Stmt::CXXMemberCallExprClass:
  case clang::Stmt::CXXOperatorCallExprClass:
  case clang::Stmt::CallExprClass: {
    clang::CallExpr* call = cast<CallExpr>(expr);

    clang::FunctionDecl *callee = call->getDirectCallee();
    if (!callee) {
      DEBUG(llvm::errs() << "UNSOUND: could not find callee for ");
      DEBUG(call->dump());
      DEBUG(llvm::errs() << "\n");
      return ecPrecise;
    }

    // Check parameters.
    // XXX this should be moved to the framework
    // XXX variadic, default args: when param/arg list lengths are not equal
    clang::FunctionDecl::param_iterator pi = callee->param_begin();
    clang::CallExpr::arg_iterator ai = call->arg_begin();
    for (; pi != callee->param_end() && ai != call->arg_end(); ++pi, ++ai) {
      assertFlow((*pi)->getType(), *ai);
    }

    DEBUG(llvm::errs() << "callee: ");
    DEBUG(callee->dump());
    DEBUG(llvm::errs() << " type: " << typeOf(callee) << "\n");

    return CL_LEAVE_UNCHANGED;
  }

  // MISC
  case clang::Stmt::ParenExprClass: {
    clang::ParenExpr* paren = cast<ParenExpr>(expr);
    return typeOf(paren->getSubExpr());
  }

  default:
    DEBUG(llvm::errs() << "UNSOUND: unhandled expression kind "
                       << expr->getStmtClass() << "\n");
    // change to getStmtClassName() for name lookup (crashes for some kinds)
    return ecPrecise;
  }
}

// Apply EnerC types to the Clang type structures.
QualType EnerCTyper::withQuals(QualType oldT, uint32_t type) {
  if (oldT.isNull())
    return oldT;

  const PointerType *ptrT = dyn_cast<PointerType>(oldT.getTypePtr());
  if (ptrT) {
    // For pointers, apply to the pointed-to type (recursively).
    ASTContext &ctx = controller->ci.getASTContext();
    QualType innerType = withQuals(ptrT->getPointeeType(), type);
    innerType = ctx.getCanonicalType(innerType);
    QualType out = ctx.getPointerType(innerType);
    out = replaceQuals(out, oldT.getQualifiers());

    if (innerType->isVoidType() && type) {
      llvm::errs() << "approx void\n";
      out.dump();
    }

    return out;
  } else {
    // For non-pointers, apply to this type.
    return NodeTyper::withQuals(oldT, type);
  }
}

void EnerCTyper::checkCondition(clang::Expr *cond) {
  // Found a statement with a condition.
  if (typeOf(cond) == ecApprox) {
    typeError(cond, "approximate condition");
  }
}

// Checking types in statements. (No type assignment here.)
void EnerCTyper::checkStmt(clang::Stmt *stmt) {
  switch (stmt->getStmtClass()) {
    // Check for approximate conditions.
    case clang::Stmt::IfStmtClass:
      checkCondition(cast<clang::IfStmt>(stmt)->getCond());
      break;
    case clang::Stmt::ForStmtClass:
      checkCondition(cast<clang::ForStmt>(stmt)->getCond());
      break;
    case clang::Stmt::DoStmtClass:
      checkCondition(cast<clang::DoStmt>(stmt)->getCond());
      break;
    case clang::Stmt::WhileStmtClass:
      checkCondition(cast<clang::WhileStmt>(stmt)->getCond());
      break;
    case clang::Stmt::SwitchStmtClass:
      checkCondition(cast<clang::SwitchStmt>(stmt)->getCond());
      break;

    // Check function return type.
    case clang::Stmt::ReturnStmtClass:
      {
        clang::Expr *expr = cast<clang::ReturnStmt>(stmt)->getRetValue();
        if (expr && curFunction) {
          assertFlow(curFunction->getResultType(), expr);
        }
      }
      break;

    // Check variable initialization.
    case clang::Stmt::DeclStmtClass:
      {
        clang::DeclStmt *dstmt = cast<clang::DeclStmt>(stmt);
        for (DeclStmt::const_decl_iterator i = dstmt->decl_begin();
             i != dstmt->decl_end(); ++i) {
          clang::VarDecl *vdecl = dyn_cast<clang::VarDecl>(*i);
          if (vdecl && vdecl->hasInit()) {
            assertFlow(vdecl->getType(), vdecl->getInit());
          }
        }
      }
      break;

    default:
      break;
  }
}
<commit_msg>special-case literal assignments<commit_after>#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/AST.h"
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/Support/raw_ostream.h"
#include "NodeTyper.h"
#include "TyperVisitor.h"
#include "llvm/Support/Debug.h"
#include <iostream>

// Random numbers unlikely to come up in source programs...
#define TAG_ENDORSEMENT 9946037276205

using namespace clang;

namespace {

// The types in the EnerC type system.
const uint32_t ecPrecise = 0;
const uint32_t ecApprox = 1;

// The typer: assign types to AST nodes.
class EnerCTyper : public NodeTyper {
public:
  virtual uint32_t typeForQualString(llvm::StringRef s);
  virtual uint32_t defaultType(clang::Decl *decl);
  virtual uint32_t typeForExpr(clang::Expr *expr);
  virtual void checkStmt(clang::Stmt *stmt);
  virtual QualType withQuals(QualType oldT, uint32_t type);
  bool compatible(uint32_t lhs, uint32_t rhs);
  bool compatible(clang::QualType lhs, clang::QualType rhs);
  bool qualsEqual(clang::QualType lhs, clang::QualType rhs);
  void assertFlow(clang::QualType type, clang::Expr *expr);

  EnerCTyper(TyperConsumer *_controller) :
    NodeTyper(_controller) {}

private:
  void checkCondition(clang::Expr *cond);
};

// Plugin hooks for Clang driver.
class EnerCTypeCheckerAction: public PluginASTAction {
protected:
  ASTConsumer *CreateASTConsumer( CompilerInstance &CI, llvm::StringRef ) {
    // Pass the type-checking visitor back to Clang so we get called to
    // traverse all ASTs.
    return new TyperVisitor<EnerCTyper>( CI );
  }

  bool ParseArgs( const CompilerInstance &CI,
                  const std::vector<std::string>& args ) {
    // No arguments.
    return true;
  }

  void PrintHelp( llvm::raw_ostream& ros ) {
    ros << "TODO\n";
  }

  virtual ~EnerCTypeCheckerAction() {
  }
};

} // end namespace

// Register the plugin.
static FrontendPluginRegistry::Add<EnerCTypeCheckerAction> X(
    "enerc-type-checker", "perform EnerC type checking" );

// Assign qualifiers to declarations based on type annotations.
uint32_t EnerCTyper::typeForQualString(llvm::StringRef s) {
  if (s.equals("approx")) {
    return ecApprox;
  } else if (s.equals("precise")) {
    return ecPrecise;
  } else {
    std::cerr << "INVALID QUALIFIER: " << s.str() << "\n";
    return ecPrecise;
  }
}

// Default type for unannotated declarations.
uint32_t EnerCTyper::defaultType(clang::Decl *decl) {
  return ecPrecise;
}

// Type compatibility: the information flow rule.
bool EnerCTyper::compatible(uint32_t lhs, uint32_t rhs) {
  if (lhs == ecPrecise) {
    if (rhs == ecPrecise)
      return true;
    else
      return false;
  } else {
    return true;
  }
}

bool EnerCTyper::compatible(clang::QualType lhs, clang::QualType rhs) {
  if (lhs.isNull() || rhs.isNull())
    return true;

  // Current type level.
  if (!compatible(lhs.getQualifiers().getCustomQuals(),
                  rhs.getQualifiers().getCustomQuals())) {
    return false;
  }

  // Possibly recuse into referent types. After the first level, all
  // qualifiers must be *equal*. This incompatibility prevents unsoundness
  // that arises when different types alias.
  if (controller->ci.getASTContext().UnwrapSimilarPointerTypes(lhs, rhs)) {
    return qualsEqual(lhs, rhs);
  } else {
    return true;
  }
}

bool EnerCTyper::qualsEqual(clang::QualType lhs, clang::QualType rhs) {
  if (lhs.isNull() || rhs.isNull())
    return true;
  if (lhs.getQualifiers().getCustomQuals() !=
      rhs.getQualifiers().getCustomQuals()) {
    return false;
  }
  if (controller->ci.getASTContext().UnwrapSimilarPointerTypes(lhs, rhs)) {
    return qualsEqual(lhs, rhs);
  } else {
    return true;
  }
}

void EnerCTyper::assertFlow(clang::QualType type, clang::Expr *expr) {
  // Special-case malloc on the RHS.
  clang::Expr *innerExpr = expr->IgnoreImplicit();
  if (clang::CastExpr *castExpr = llvm::dyn_cast<clang::CastExpr>(innerExpr)) {
    innerExpr = castExpr->getSubExpr();
    innerExpr = innerExpr->IgnoreImplicit();
  }
  if (clang::CallExpr *callExpr = llvm::dyn_cast<clang::CallExpr>(innerExpr))
    if (clang::FunctionDecl *fdecl = callExpr->getDirectCallee())
      if (fdecl->getNameAsString() == "malloc")
        return;

  // Special-case literals (APPROX int* p = 0;).
  if (llvm::isa<clang::IntegerLiteral>(innerExpr))
    return;

  // Other cases.
  assertCompatible(type, expr, "precision flow violation");
}

// Give types to expressions.
uint32_t EnerCTyper::typeForExpr(clang::Expr *expr) {
  // Tolerate null.
  if (!expr)
    return ecPrecise;

  switch ( expr->getStmtClass() ) {

  // LITERALS
  case clang::Stmt::CharacterLiteralClass:
  case clang::Stmt::IntegerLiteralClass:
  case clang::Stmt::StringLiteralClass:
  case clang::Stmt::ImaginaryLiteralClass:
  case clang::Stmt::CompoundLiteralExprClass:
  case clang::Stmt::CXXBoolLiteralExprClass:
  case clang::Stmt::CXXNullPtrLiteralExprClass:
  case clang::Stmt::GNUNullExprClass:
  case clang::Stmt::FloatingLiteralClass:
  case clang::Stmt::UnaryTypeTraitExprClass:
  case clang::Stmt::CXXConstructExprClass:
  case clang::Stmt::CXXNewExprClass:
  case clang::Stmt::CXXDeleteExprClass:
  case clang::Stmt::OffsetOfExprClass:
  case clang::Stmt::SizeOfPackExprClass:
    return ecPrecise;

  // VARIABLE REFERENCES
//  case clang::Stmt::BlockDeclRefExprClass: {
//    clang::BlockDeclRefExpr* tex = cast<clang::BlockDeclRefExpr>(expr);
//    return typeOf(tex->getDecl());
//  }
  case clang::Stmt::DeclRefExprClass:
    return CL_LEAVE_UNCHANGED;
  case clang::Stmt::DependentScopeDeclRefExprClass: {
    DEBUG(llvm::errs() << "UNSOUND: template argument untypable\n");
    return ecPrecise;
  }
  case clang::Stmt::MemberExprClass:
    return CL_LEAVE_UNCHANGED;

  // CASTS
  // In all cases, we just propagate the qualifier of the casted expression.
  // This is especially important for implicit casts, but for explicit casts we
  // might eventually want to allow qualifiers -- but that should probably only
  // be done with endorsements.
  case clang::Stmt::ImplicitCastExprClass:
    return CL_LEAVE_UNCHANGED;

  case clang::Stmt::CStyleCastExprClass:
  case clang::Stmt::CXXFunctionalCastExprClass:
  case clang::Stmt::CXXConstCastExprClass:
  case clang::Stmt::CXXDynamicCastExprClass:
  case clang::Stmt::CXXReinterpretCastExprClass:
  case clang::Stmt::CXXStaticCastExprClass:
    return typeOf(cast<clang::CastExpr>(expr)->getSubExpr());

  // BINARY OPERATORS
  case clang::Stmt::BinaryOperatorClass: {
    clang::BinaryOperator *bop = llvm::cast<BinaryOperator>(expr);
    DEBUG(llvm::errs() << "binary operator " << bop->getOpcode() << "\n");
    DEBUG(bop->getLHS()->dump());
    DEBUG(bop->getRHS()->dump());
    uint32_t ltype = typeOf(bop->getLHS());
    uint32_t rtype = typeOf(bop->getRHS());

    DEBUG(llvm::errs() << "left " << ltype << " right " << rtype << "\n");

    switch (bop->getOpcode()) {
      case BO_Mul:
      case BO_Div:
      case BO_Rem:
      case BO_Add:
      case BO_Sub:
      case BO_Shl:
      case BO_Shr:
      case BO_LT:
      case BO_GT:
      case BO_LE:
      case BO_GE:
      case BO_EQ:
      case BO_NE:
      case BO_And:
      case BO_Xor:
      case BO_Or:
      case BO_LAnd:
      case BO_LOr:
        DEBUG(llvm::errs() << "arithmetic\n");
        if (ltype == ecApprox || rtype == ecApprox)
          return ecApprox;
        else
          return ecPrecise;

      case BO_Assign:
      case BO_MulAssign:
      case BO_DivAssign:
      case BO_RemAssign:
      case BO_AddAssign:
      case BO_SubAssign:
      case BO_ShlAssign:
      case BO_ShrAssign:
      case BO_AndAssign:
      case BO_XorAssign:
      case BO_OrAssign:
        DEBUG(llvm::errs() << "assignment\n");
        assertFlow(bop->getLHS()->getType(), bop->getRHS());
        return ltype;

      case BO_Comma:
        {
          // Endorsements are encoded as comma expressions!
          clang::IntegerLiteral *literal =
              dyn_cast<clang::IntegerLiteral>(bop->getLHS());
          if (literal && literal->getValue() == TAG_ENDORSEMENT) {
            // This is an endorsement of the right-hand expression.
            return ecPrecise;
          } else {
            // An ordinary comma expression.
            return CL_LEAVE_UNCHANGED;
          }
        }

      case BO_PtrMemD:
      case BO_PtrMemI:
        DEBUG(llvm::errs() << "UNSOUND: unimplemented: pointer-to-mem\n");
        return ecPrecise;
    }
  }

  // UNARY OPERATORS
  case clang::Stmt::UnaryOperatorClass: {
    clang::UnaryOperator *uop = llvm::cast<UnaryOperator>(expr);
    uint32_t argt = typeOf(uop->getSubExpr());
    switch (uop->getOpcode()) {
      case UO_PostInc:
      case UO_PostDec:
      case UO_PreInc:
      case UO_PreDec:
      case UO_Plus:
      case UO_Minus:
      case UO_Not:
      case UO_LNot:
        // arithmetic
        return argt;

      case UO_AddrOf:
      case UO_Deref:
        return CL_LEAVE_UNCHANGED;

      case UO_Real:
      case UO_Imag:
      case UO_Extension:
        // funky complex stuff
        return argt;
    }
  }

  // ARRAYS
  case clang::Stmt::ArraySubscriptExprClass:
    return CL_LEAVE_UNCHANGED;

  // FUNCTION CALLS
  case clang::Stmt::CXXMemberCallExprClass:
  case clang::Stmt::CXXOperatorCallExprClass:
  case clang::Stmt::CallExprClass: {
    clang::CallExpr* call = cast<CallExpr>(expr);

    clang::FunctionDecl *callee = call->getDirectCallee();
    if (!callee) {
      DEBUG(llvm::errs() << "UNSOUND: could not find callee for ");
      DEBUG(call->dump());
      DEBUG(llvm::errs() << "\n");
      return ecPrecise;
    }

    // Check parameters.
    // XXX this should be moved to the framework
    // XXX variadic, default args: when param/arg list lengths are not equal
    clang::FunctionDecl::param_iterator pi = callee->param_begin();
    clang::CallExpr::arg_iterator ai = call->arg_begin();
    for (; pi != callee->param_end() && ai != call->arg_end(); ++pi, ++ai) {
      assertFlow((*pi)->getType(), *ai);
    }

    DEBUG(llvm::errs() << "callee: ");
    DEBUG(callee->dump());
    DEBUG(llvm::errs() << " type: " << typeOf(callee) << "\n");

    return CL_LEAVE_UNCHANGED;
  }

  // MISC
  case clang::Stmt::ParenExprClass: {
    clang::ParenExpr* paren = cast<ParenExpr>(expr);
    return typeOf(paren->getSubExpr());
  }

  default:
    DEBUG(llvm::errs() << "UNSOUND: unhandled expression kind "
                       << expr->getStmtClass() << "\n");
    // change to getStmtClassName() for name lookup (crashes for some kinds)
    return ecPrecise;
  }
}

// Apply EnerC types to the Clang type structures.
QualType EnerCTyper::withQuals(QualType oldT, uint32_t type) {
  if (oldT.isNull())
    return oldT;

  const PointerType *ptrT = dyn_cast<PointerType>(oldT.getTypePtr());
  if (ptrT) {
    // For pointers, apply to the pointed-to type (recursively).
    ASTContext &ctx = controller->ci.getASTContext();
    QualType innerType = withQuals(ptrT->getPointeeType(), type);
    innerType = ctx.getCanonicalType(innerType);
    QualType out = ctx.getPointerType(innerType);
    out = replaceQuals(out, oldT.getQualifiers());

    if (innerType->isVoidType() && type) {
      llvm::errs() << "approx void\n";
      out.dump();
    }

    return out;
  } else {
    // For non-pointers, apply to this type.
    return NodeTyper::withQuals(oldT, type);
  }
}

void EnerCTyper::checkCondition(clang::Expr *cond) {
  // Found a statement with a condition.
  if (typeOf(cond) == ecApprox) {
    typeError(cond, "approximate condition");
  }
}

// Checking types in statements. (No type assignment here.)
void EnerCTyper::checkStmt(clang::Stmt *stmt) {
  switch (stmt->getStmtClass()) {
    // Check for approximate conditions.
    case clang::Stmt::IfStmtClass:
      checkCondition(cast<clang::IfStmt>(stmt)->getCond());
      break;
    case clang::Stmt::ForStmtClass:
      checkCondition(cast<clang::ForStmt>(stmt)->getCond());
      break;
    case clang::Stmt::DoStmtClass:
      checkCondition(cast<clang::DoStmt>(stmt)->getCond());
      break;
    case clang::Stmt::WhileStmtClass:
      checkCondition(cast<clang::WhileStmt>(stmt)->getCond());
      break;
    case clang::Stmt::SwitchStmtClass:
      checkCondition(cast<clang::SwitchStmt>(stmt)->getCond());
      break;

    // Check function return type.
    case clang::Stmt::ReturnStmtClass:
      {
        clang::Expr *expr = cast<clang::ReturnStmt>(stmt)->getRetValue();
        if (expr && curFunction) {
          assertFlow(curFunction->getResultType(), expr);
        }
      }
      break;

    // Check variable initialization.
    case clang::Stmt::DeclStmtClass:
      {
        clang::DeclStmt *dstmt = cast<clang::DeclStmt>(stmt);
        for (DeclStmt::const_decl_iterator i = dstmt->decl_begin();
             i != dstmt->decl_end(); ++i) {
          clang::VarDecl *vdecl = dyn_cast<clang::VarDecl>(*i);
          if (vdecl && vdecl->hasInit()) {
            assertFlow(vdecl->getType(), vdecl->getInit());
          }
        }
      }
      break;

    default:
      break;
  }
}
<|endoftext|>


<commit_before>// @(#)root/tmva $Id$
// Author: Omar Zapata, Thomas James Stevenson.

#include <iostream>

#include "TMVA/CrossValidation.h"
#include "TMVA/MethodBase.h"
#include "TMVA/ResultsClassification.h"
#include "TSystem.h"
#include "TAxis.h"
#include "TCanvas.h"
#include "TGraph.h"
#include <memory>
#include "TMVA/tmvaglob.h"

TMVA::CrossValidationResult::CrossValidationResult():fROCCurves(new TMultiGraph())
{
}

TMVA::CrossValidationResult::CrossValidationResult(const CrossValidationResult &obj)
{
    fROCs=obj.fROCs;
    fROCCurves = obj.fROCCurves;
}

TMultiGraph *TMVA::CrossValidationResult::GetROCCurves(Bool_t /*fLegend*/)
{
    return fROCCurves.get();
}

Float_t TMVA::CrossValidationResult::GetROCAverage() const
{
    Float_t avg=0;
    for(auto &roc:fROCs) avg+=roc.second;
    return avg/fROCs.size();
}

void TMVA::CrossValidationResult::Print() const
{
    TMVA::MsgLogger::EnableOutput();
    TMVA::gConfig().SetSilent(kFALSE);

    MsgLogger fLogger("CrossValidation");
    for(auto &item:fROCs)
        fLogger<<kINFO<<Form("Fold  %i ROC-Int : %f",item.first,item.second)<<std::endl;

    fLogger<<kINFO<<Form("Average ROC-Int : %f",GetROCAverage())<<Endl;

    TMVA::gConfig().SetSilent(kTRUE);

}

TCanvas* TMVA::CrossValidationResult::Draw(const TString name) const
{
    TCanvas *c=new TCanvas(name.Data());
    fROCCurves->Draw("AL");
    fROCCurves->GetXaxis()->SetTitle(" Signal Efficiency ");
    fROCCurves->GetYaxis()->SetTitle(" Background Rejection ");
    Float_t adjust=1+fROCs.size()*0.01;
    c->BuildLegend(0.15,0.15,0.4*adjust,0.5*adjust);
    c->SetTitle("Cross Validation ROC Curves");
    c->Draw();
    return c;
}

TMVA::CrossValidation::CrossValidation(TMVA::DataLoader *dataloader):TMVA::Envelope("CrossValidation",dataloader),
fNumFolds(5),fClassifier(new TMVA::Factory("CrossValidation","!V:!ROC:Silent:!ModelPersistence:!Color:!DrawProgressBar:AnalysisType=Classification"))
{
    fFoldStatus=kFALSE;
}

TMVA::CrossValidation::~CrossValidation()
{
    fClassifier=nullptr;
}

void TMVA::CrossValidation::SetNumFolds(UInt_t i)
{
    fNumFolds=i;
    fDataLoader->MakeKFoldDataSet(fNumFolds);
    fFoldStatus=kTRUE;
}

void TMVA::CrossValidation::Evaluate()
{
    TString methodName    = fMethod.GetValue<TString>("MethodName");
    TString methodTitle   = fMethod.GetValue<TString>("MethodTitle");
    TString methodOptions = fMethod.GetValue<TString>("MethodOptions");
    if(!fFoldStatus)
    {
        fDataLoader->MakeKFoldDataSet(fNumFolds);
        fFoldStatus=kTRUE;
    }

      for(UInt_t i = 0; i < fNumFolds; ++i){
        TString foldTitle = methodTitle;
        foldTitle += "_fold";
        foldTitle += i+1;

        fDataLoader->PrepareFoldDataSet(i, TMVA::Types::kTesting);

        auto smethod=fClassifier->BookMethod(fDataLoader.get(), methodName, methodTitle, methodOptions);

        Event::SetIsTraining(kTRUE);
        smethod->TrainMethod();

        Event::SetIsTraining(kFALSE);
        smethod->AddOutput(Types::kTesting, smethod->GetAnalysisType());
        smethod->TestClassification();

        fResults.fROCs[i]=fClassifier->GetROCIntegral(fDataLoader->GetName(),methodTitle);

        auto  gr=fClassifier->GetROCCurve(fDataLoader->GetName(), methodTitle, true);

        gr->SetLineColor(i+1);
        gr->SetLineWidth(2);
        gr->SetTitle(fDataLoader->GetName());

        fResults.fROCCurves->Add(gr);

        fResults.fSigs.push_back(smethod->GetSignificance());
        fResults.fSeps.push_back(smethod->GetSeparation());

        Double_t err;
        fResults.fEff01s.push_back(smethod->GetEfficiency("Efficiency:0.01",Types::kTesting, err));
        fResults.fEff10s.push_back(smethod->GetEfficiency("Efficiency:0.10",Types::kTesting,err));
        fResults.fEff30s.push_back(smethod->GetEfficiency("Efficiency:0.30",Types::kTesting,err));
        fResults.fEffAreas.push_back(smethod->GetEfficiency(""             ,Types::kTesting,err));
        fResults.fTrainEff01s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.01"));
        fResults.fTrainEff10s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.10"));
        fResults.fTrainEff30s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.30"));

        smethod->Data()->DeleteResults(smethod->GetMethodName(), Types::kTesting, Types::kClassification);
        smethod->Data()->DeleteResults(smethod->GetMethodName(), Types::kTraining, Types::kClassification);

        fClassifier->DeleteAllMethods();
        fClassifier->fMethodsMap.clear();
        }
        TMVA::MsgLogger::EnableOutput();
        TMVA::gConfig().SetSilent(kFALSE);
        Log()<<kINFO<<"Evaluation done."<<Endl;
        TMVA::gConfig().SetSilent(kTRUE);

}
<commit_msg>TMVA:fixed names in ROC plots for CV<commit_after>// @(#)root/tmva $Id$
// Author: Omar Zapata, Thomas James Stevenson.

#include <iostream>

#include "TMVA/CrossValidation.h"
#include "TMVA/MethodBase.h"
#include "TMVA/ResultsClassification.h"
#include "TSystem.h"
#include "TAxis.h"
#include "TCanvas.h"
#include "TGraph.h"
#include <memory>
#include "TMVA/tmvaglob.h"

TMVA::CrossValidationResult::CrossValidationResult():fROCCurves(new TMultiGraph())
{
}

TMVA::CrossValidationResult::CrossValidationResult(const CrossValidationResult &obj)
{
    fROCs=obj.fROCs;
    fROCCurves = obj.fROCCurves;
}

TMultiGraph *TMVA::CrossValidationResult::GetROCCurves(Bool_t /*fLegend*/)
{
    return fROCCurves.get();
}

Float_t TMVA::CrossValidationResult::GetROCAverage() const
{
    Float_t avg=0;
    for(auto &roc:fROCs) avg+=roc.second;
    return avg/fROCs.size();
}

void TMVA::CrossValidationResult::Print() const
{
    TMVA::MsgLogger::EnableOutput();
    TMVA::gConfig().SetSilent(kFALSE);

    MsgLogger fLogger("CrossValidation");
    for(auto &item:fROCs)
        fLogger<<kINFO<<Form("Fold  %i ROC-Int : %f",item.first,item.second)<<std::endl;

    fLogger<<kINFO<<Form("Average ROC-Int : %f",GetROCAverage())<<Endl;

    TMVA::gConfig().SetSilent(kTRUE);

}

TCanvas* TMVA::CrossValidationResult::Draw(const TString name) const
{
    TCanvas *c=new TCanvas(name.Data());
    fROCCurves->Draw("AL");
    fROCCurves->GetXaxis()->SetTitle(" Signal Efficiency ");
    fROCCurves->GetYaxis()->SetTitle(" Background Rejection ");
    Float_t adjust=1+fROCs.size()*0.01;
    c->BuildLegend(0.15,0.15,0.4*adjust,0.5*adjust);
    c->SetTitle("Cross Validation ROC Curves");
    c->Draw();
    return c;
}

TMVA::CrossValidation::CrossValidation(TMVA::DataLoader *dataloader):TMVA::Envelope("CrossValidation",dataloader),
fNumFolds(5),fClassifier(new TMVA::Factory("CrossValidation","!V:!ROC:Silent:!ModelPersistence:!Color:!DrawProgressBar:AnalysisType=Classification"))
{
    fFoldStatus=kFALSE;
}

TMVA::CrossValidation::~CrossValidation()
{
    fClassifier=nullptr;
}

void TMVA::CrossValidation::SetNumFolds(UInt_t i)
{
    fNumFolds=i;
    fDataLoader->MakeKFoldDataSet(fNumFolds);
    fFoldStatus=kTRUE;
}

void TMVA::CrossValidation::Evaluate()
{
    TString methodName    = fMethod.GetValue<TString>("MethodName");
    TString methodTitle   = fMethod.GetValue<TString>("MethodTitle");
    TString methodOptions = fMethod.GetValue<TString>("MethodOptions");
    if(!fFoldStatus)
    {
        fDataLoader->MakeKFoldDataSet(fNumFolds);
        fFoldStatus=kTRUE;
    }

      for(UInt_t i = 0; i < fNumFolds; ++i){
        TString foldTitle = methodTitle;
        foldTitle += "_fold";
        foldTitle += i+1;

        fDataLoader->PrepareFoldDataSet(i, TMVA::Types::kTesting);

        auto smethod=fClassifier->BookMethod(fDataLoader.get(), methodName, methodTitle, methodOptions);

        Event::SetIsTraining(kTRUE);
        smethod->TrainMethod();

        Event::SetIsTraining(kFALSE);
        smethod->AddOutput(Types::kTesting, smethod->GetAnalysisType());
        smethod->TestClassification();

        fResults.fROCs[i]=fClassifier->GetROCIntegral(fDataLoader->GetName(),methodTitle);

        auto  gr=fClassifier->GetROCCurve(fDataLoader->GetName(), methodTitle, true);

        gr->SetLineColor(i+1);
        gr->SetLineWidth(2);
        gr->SetTitle(foldTitle.Data());

        fResults.fROCCurves->Add(gr);

        fResults.fSigs.push_back(smethod->GetSignificance());
        fResults.fSeps.push_back(smethod->GetSeparation());

        Double_t err;
        fResults.fEff01s.push_back(smethod->GetEfficiency("Efficiency:0.01",Types::kTesting, err));
        fResults.fEff10s.push_back(smethod->GetEfficiency("Efficiency:0.10",Types::kTesting,err));
        fResults.fEff30s.push_back(smethod->GetEfficiency("Efficiency:0.30",Types::kTesting,err));
        fResults.fEffAreas.push_back(smethod->GetEfficiency(""             ,Types::kTesting,err));
        fResults.fTrainEff01s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.01"));
        fResults.fTrainEff10s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.10"));
        fResults.fTrainEff30s.push_back(smethod->GetTrainingEfficiency("Efficiency:0.30"));

        smethod->Data()->DeleteResults(smethod->GetMethodName(), Types::kTesting, Types::kClassification);
        smethod->Data()->DeleteResults(smethod->GetMethodName(), Types::kTraining, Types::kClassification);

        fClassifier->DeleteAllMethods();
        fClassifier->fMethodsMap.clear();
        }
        TMVA::MsgLogger::EnableOutput();
        TMVA::gConfig().SetSilent(kFALSE);
        Log()<<kINFO<<"Evaluation done."<<Endl;
        TMVA::gConfig().SetSilent(kTRUE);

}
<|endoftext|>


<commit_before><commit_msg>Coverity: Free the loaded sandbox test module library.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "build/build_config.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class GPUTest : public UITest {
 protected:
  GPUTest() {
  }

  virtual void SetUp() {
    UITest::SetUp();
    gpu_test_dir_ = test_data_directory_.AppendASCII("gpu");
  }

  FilePath gpu_test_dir_;
};

// TODO(apatrick): Other pending changes will fix this for mac.
#if defined(OS_MACOSX)
#define MAYBE_UITestLaunchedWithOSMesa DISABLED_UITestLaunchedWithOSMesa
#else
#define MAYBE_UITestLaunchedWithOSMesa UITestLaunchedWithOSMesa
#endif

TEST_F(GPUTest, MAYBE_UITestLaunchedWithOSMesa) {
  // Check the webgl test reports success and that the renderer was OSMesa.
  // We use OSMesa for tests in order to get consistent results across a
  // variety of boxes.
  NavigateToURL(
      net::FilePathToFileURL(gpu_test_dir_.AppendASCII("webgl.html")));

  EXPECT_EQ(std::wstring(L"SUCCESS: Mesa OffScreen"), GetActiveTabTitle());
}
<commit_msg>Marked GPUUITest.UITestLaunchedWithOSMesa disabled on Windows.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "build/build_config.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"

class GPUUITest : public UITest {
 protected:
  GPUUITest() {
  }

  virtual void SetUp() {
    UITest::SetUp();
    gpu_test_dir_ = test_data_directory_.AppendASCII("gpu");
  }

  FilePath gpu_test_dir_;
};

#if defined(OS_WIN) || defined(OS_MACOSX)
#define MAYBE_UITestLaunchedWithOSMesa DISABLED_UITestLaunchedWithOSMesa
#else
#define MAYBE_UITestLaunchedWithOSMesa UITestLaunchedWithOSMesa
#endif

TEST_F(GPUUITest, MAYBE_UITestLaunchedWithOSMesa) {
  // Check the webgl test reports success and that the renderer was OSMesa.
  // We use OSMesa for tests in order to get consistent results across a
  // variety of boxes.
  NavigateToURL(
      net::FilePathToFileURL(gpu_test_dir_.AppendASCII("webgl.html")));

  EXPECT_EQ(std::wstring(L"SUCCESS: Mesa OffScreen"), GetActiveTabTitle());
}
<|endoftext|>


<commit_before>#ifndef NODE_HPP
#define NODE_HPP

#include <memory>
#include <utility>

#include "../Assert.hpp"

#include "Operator.hpp"
#include "Variable.hpp"

struct Node;
using NodePtr = std::unique_ptr<Node>;

struct Node
{
    enum class Type
    {
        VALUE,
        VARIABLE,
        OPERATION,
        COUNT
    };

    virtual Type type() const = 0;
    virtual int eval(const VariableMap* map) const = 0;
    virtual NodePtr clone() const = 0;
};

template <class T, class... Args>
NodePtr node(Args&&... args)
{
    return std::make_unique<T>(std::forward<Args>(args)...);
}

struct ValueNode : public Node
{
    int value;
    ValueNode(int value) :
        value(value)
    {
    }

    virtual Type type() const override
    {
        return Type::VALUE;
    }

    virtual int eval(const VariableMap* map) const override
    {
        return value;
    }

    virtual NodePtr clone() const { return node<ValueNode>(value); }
};

struct VariableNode : public Node
{
    Variable id;

    VariableNode(const Variable& id) : id(id) {}

    virtual Type type() const override
    {
        return Type::VARIABLE;
    }

    virtual int eval(const VariableMap* map) const override
    {
        return map != nullptr && map->find(id) == map->end() ? 0 : map->at(id);
    }

    virtual NodePtr clone() const override { return node<VariableNode>(id); }
};

struct OperatorNode : public Node
{
    Operator op;
    NodePtr left;
    NodePtr right;

    OperatorNode(Operator op, NodePtr left, NodePtr right) :
        op{op}, left{std::move(left)}, right{std::move(right)}
    {
    }

    virtual Type type() const override
    {
        return Type::OPERATION;
    }

    virtual int eval(const VariableMap* map) const override
    {
        // special case for division and variable nodes. i.e. x/x == 1 for all x in real (including 0)
        if(op == Operator::DIVIDE_SAFE)/*|| op == Operator::DIVIDE)*/
        {
            if(left->type() == Node::Type::VARIABLE && right->type() == Node::Type::VARIABLE &&
               static_cast<VariableNode*>(left.get())->id == static_cast<VariableNode*>(right.get())->id)
            {
                return 1;
            }
        }

        return ::eval(left->eval(map), right->eval(map), op);
    }

    virtual NodePtr clone() const override { return node<OperatorNode>(op, left == nullptr ? nullptr : std::move(left->clone()), right == nullptr ? nullptr : std::move(right->clone())); }
};

#endif // NODE_HPP
<commit_msg>Fixed crazy memory leak due to not having a virtual dtor<commit_after>#ifndef NODE_HPP
#define NODE_HPP

#include <memory>
#include <utility>

#include "../Assert.hpp"

#include "Operator.hpp"
#include "Variable.hpp"

struct Node;
using NodePtr = std::unique_ptr<Node>;

struct Node
{
    enum class Type
    {
        VALUE,
        VARIABLE,
        OPERATION,
        COUNT
    };

    virtual Type type() const = 0;
    virtual int eval(const VariableMap* map) const = 0;
    virtual NodePtr clone() const = 0;
    virtual ~Node() { }
};

template <class T, class... Args>
NodePtr node(Args&&... args)
{
    return std::make_unique<T>(std::forward<Args>(args)...);
}

struct ValueNode : public Node
{
    int value;
    ValueNode(int value) :
        value(value)
    {
    }

    virtual ~ValueNode() { }

    virtual Type type() const override
    {
        return Type::VALUE;
    }

    virtual int eval(const VariableMap* map) const override
    {
        return value;
    }

    virtual NodePtr clone() const { return node<ValueNode>(value); }
};

struct VariableNode : public Node
{
    Variable id;

    VariableNode(const Variable& id) : id(id) {}

    virtual ~VariableNode() { }

    virtual Type type() const override
    {
        return Type::VARIABLE;
    }

    virtual int eval(const VariableMap* map) const override
    {
        return map != nullptr && map->find(id) == map->end() ? 0 : map->at(id);
    }

    virtual NodePtr clone() const override { return node<VariableNode>(id); }
};

struct OperatorNode : public Node
{
    Operator op;
    NodePtr left;
    NodePtr right;

    OperatorNode(Operator op, NodePtr left, NodePtr right) :
        op{op}, left{std::move(left)}, right{std::move(right)}
    {
    }

    virtual ~OperatorNode() { }

    virtual Type type() const override
    {
        return Type::OPERATION;
    }

    virtual int eval(const VariableMap* map) const override
    {
        // special case for division and variable nodes. i.e. x/x == 1 for all x in real (including 0)
        if(op == Operator::DIVIDE_SAFE)/*|| op == Operator::DIVIDE)*/
        {
            if(left->type() == Node::Type::VARIABLE && right->type() == Node::Type::VARIABLE &&
               static_cast<VariableNode*>(left.get())->id == static_cast<VariableNode*>(right.get())->id)
            {
                return 1;
            }
        }

        return ::eval(left->eval(map), right->eval(map), op);
    }

    virtual NodePtr clone() const override { return node<OperatorNode>(op, left == nullptr ? nullptr : std::move(left->clone()), right == nullptr ? nullptr : std::move(right->clone())); }
};

#endif // NODE_HPP
<|endoftext|>


<commit_before>//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-format tool that automatically formats
/// (fragments of) C++ code.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/FileSystem.h"

using namespace llvm;

static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);

static cl::opt<int> Offset(
    "offset", cl::desc("Format a range starting at this file offset."),
    cl::init(0));
static cl::opt<int> Length(
    "length", cl::desc("Format a range of this length, -1 for end of file."),
    cl::init(-1));
static cl::opt<std::string> Style(
    "style", cl::desc("Coding style, currently supports: LLVM, Google."),
    cl::init("LLVM"));
static cl::opt<bool> Inplace("i",
                             cl::desc("Inplace edit <file>, if specified."));

static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),
                                     cl::init("-"));

namespace clang {
namespace format {

static FileID createInMemoryFile(const MemoryBuffer *Source,
                                 SourceManager &Sources, FileManager &Files) {
  const FileEntry *Entry =
      Files.getVirtualFile("<stdio>", Source->getBufferSize(), 0);
  Sources.overrideFileContents(Entry, Source, true);
  return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}

static void format() {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return;
  }
  FileID ID = createInMemoryFile(Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  SourceLocation Start =
      Sources.getLocForStartOfFile(ID).getLocWithOffset(Offset);
  SourceLocation End = Sources.getLocForEndOfFile(ID);
  if (Length != -1)
    End = Start.getLocWithOffset(Length);
  std::vector<CharSourceRange> Ranges(
      1, CharSourceRange::getCharRange(Start, End));
  FormatStyle FStyle = Style == "LLVM" ? getLLVMStyle() : getGoogleStyle();
  tooling::Replacements Replaces = reformat(FStyle, Lex, Sources, Ranges);
  Rewriter Rewrite(Sources, LangOptions());
  tooling::applyAllReplacements(Replaces, Rewrite);
  if (Inplace) {
    std::string ErrorInfo;
    llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                    llvm::raw_fd_ostream::F_Binary);
    if (!ErrorInfo.empty()) {
      llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
      return;
    }
    Rewrite.getEditBuffer(ID).write(FileStream);
    FileStream.flush();
  } else {
    Rewrite.getEditBuffer(ID).write(outs());
  }
}

}  // namespace format
}  // namespace clang

int main(int argc, const char **argv) {
  cl::ParseCommandLineOptions(
      argc, argv,
      "A tool to format C/C++/Obj-C code.\n\n"
      "Currently supports LLVM and Google style guides.\n"
      "If no arguments are specified, it formats the code from standard input\n"
      "and writes the result to the standard output.\n"
      "If <file> is given, it reformats the file. If -i is specified together\n"
      "with <file>, the file is edited in-place. Otherwise, the result is\n"
      "written to the standard output.\n");
  if (Help)
    cl::PrintHelpMessage();
  clang::format::format();
  return 0;
}
<commit_msg>Fix: correct file name in diagnostics.<commit_after>//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-format tool that automatically formats
/// (fragments of) C++ code.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/FileSystem.h"

using namespace llvm;

static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);

static cl::opt<int> Offset(
    "offset", cl::desc("Format a range starting at this file offset."),
    cl::init(0));
static cl::opt<int> Length(
    "length", cl::desc("Format a range of this length, -1 for end of file."),
    cl::init(-1));
static cl::opt<std::string> Style(
    "style", cl::desc("Coding style, currently supports: LLVM, Google."),
    cl::init("LLVM"));
static cl::opt<bool> Inplace("i",
                             cl::desc("Inplace edit <file>, if specified."));

static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),
                                     cl::init("-"));

namespace clang {
namespace format {

static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
                                 SourceManager &Sources, FileManager &Files) {
  const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
                                                    FileName,
                                                Source->getBufferSize(), 0);
  Sources.overrideFileContents(Entry, Source, true);
  return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}

static void format() {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  SourceLocation Start =
      Sources.getLocForStartOfFile(ID).getLocWithOffset(Offset);
  SourceLocation End = Sources.getLocForEndOfFile(ID);
  if (Length != -1)
    End = Start.getLocWithOffset(Length);
  std::vector<CharSourceRange> Ranges(
      1, CharSourceRange::getCharRange(Start, End));
  FormatStyle FStyle = Style == "LLVM" ? getLLVMStyle() : getGoogleStyle();
  tooling::Replacements Replaces = reformat(FStyle, Lex, Sources, Ranges);
  Rewriter Rewrite(Sources, LangOptions());
  tooling::applyAllReplacements(Replaces, Rewrite);
  if (Inplace) {
    std::string ErrorInfo;
    llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                    llvm::raw_fd_ostream::F_Binary);
    if (!ErrorInfo.empty()) {
      llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
      return;
    }
    Rewrite.getEditBuffer(ID).write(FileStream);
    FileStream.flush();
  } else {
    Rewrite.getEditBuffer(ID).write(outs());
  }
}

}  // namespace format
}  // namespace clang

int main(int argc, const char **argv) {
  cl::ParseCommandLineOptions(
      argc, argv,
      "A tool to format C/C++/Obj-C code.\n\n"
      "Currently supports LLVM and Google style guides.\n"
      "If no arguments are specified, it formats the code from standard input\n"
      "and writes the result to the standard output.\n"
      "If <file> is given, it reformats the file. If -i is specified together\n"
      "with <file>, the file is edited in-place. Otherwise, the result is\n"
      "written to the standard output.\n");
  if (Help)
    cl::PrintHelpMessage();
  clang::format::format();
  return 0;
}
<|endoftext|>


<commit_before>#include <vector>
#include <cstdint>
#include <cassert>

namespace spn {
	//! 複数のバッファ形式を1つに纏める
	template <class T, class Buff=std::vector<T>>
	class AbstBuffer {
		enum class Type {
			ConstPtr,
			Movable,
			Const,
			Invalid
		};
		Type _type;
		union {
			const T*	_pSrc;
			Buff*		_buffM;
			const Buff*	_buffC;
		};
		size_t	_size;

		void _invalidate() {
			_pSrc = nullptr;
			_type = Type::Invalid;
			_size = 0;
		}

	public:
		// 中身がMovableな時にちょっと微妙だけど後で考える
		AbstBuffer(const AbstBuffer& ab) {
			_type = ab._type;
			_pSrc = ab._pSrc;
			_size = ab._size;
		}
		//! initialize by const-pointer
		AbstBuffer(const void* src, size_t sz): _type(Type::ConstPtr), _size(sz), _pSrc(reinterpret_cast<const T*>(src)) {}
		//! initialize by movable-vector
		AbstBuffer(Buff&& buff): _type(Type::Movable), _buffM(&buff), _size(buff.size()) {}
		//! initialize by const-vector
		AbstBuffer(const Buff& buff): _type(Type::Const), _buffC(&buff), _size(buff.size()) {}

		void setTo(Buff& dst) {
			switch(_type) {
				case Type::ConstPtr:
					dst.assign(_pSrc, _pSrc+_size);
					break;
				case Type::Movable:
					dst = std::move(*_buffM);
					_invalidate();
					break;
				case Type::Const:
					dst = *_buffC;
					break;
				default:
					assert(false);
					break;
			}
		}
		Buff moveTo() {
			switch(_type) {
				case Type::ConstPtr: return Buff(_pSrc, _pSrc+_size);
				case Type::Movable: return std::move(*_buffM);
				case Type::Const: return *_buffC;
				default: assert(false);
			}
		}

		size_t getSize() const {
			return _size;
		}
		const T* getPtr() const {
			if(_type == Type::ConstPtr)
				return _pSrc;
			return &(*_buffC)[0];
		}
	};

	size_t GetLength(const char* str);
	size_t GetLength(const char16_t* str);
	size_t GetLength(const char32_t* str);
	template <class T>
	class AbstString : public AbstBuffer<T, std::basic_string<T>> {
		using base_type = AbstBuffer<T, std::basic_string<T>>;
		using Str = std::basic_string<T>;
		public:
			// 文字数カウント機能を追加
			AbstString(const T* src): base_type(src, GetLength(src)) {}
			AbstString(const T* src, size_t len): base_type(src, len) {}
			AbstString(Str&& str): base_type(std::move(str)) {}
			AbstString(const Str& str): base_type(str) {}
	};
	using c8Str = AbstString<char>;
	using c16Str = AbstString<char16_t>;
	using c32Str = AbstString<char32_t>;
	using c8Buff = AbstBuffer<char>;
	using c16Buff = AbstBuffer<char16_t>;
	using c32Buff = AbstBuffer<char32_t>;

	using ByteBuff = std::vector<uint8_t>;
	using U16Buff = std::vector<uint16_t>;
	using FloatBuff = std::vector<float>;
	using AB_Byte = AbstBuffer<uint8_t>;
	using AB_U16 = AbstBuffer<uint16_t>;
	using AB_Float = AbstBuffer<float>;
}
<commit_msg>AbstBufferヘッダのインクルードガード忘れを修正<commit_after>#pragma once
#include <vector>
#include <cstdint>
#include <cassert>

namespace spn {
	//! 複数のバッファ形式を1つに纏める
	template <class T, class Buff=std::vector<T>>
	class AbstBuffer {
		enum class Type {
			ConstPtr,
			Movable,
			Const,
			Invalid
		};
		Type _type;
		union {
			const T*	_pSrc;
			Buff*		_buffM;
			const Buff*	_buffC;
		};
		size_t	_size;

		void _invalidate() {
			_pSrc = nullptr;
			_type = Type::Invalid;
			_size = 0;
		}

	public:
		// 中身がMovableな時にちょっと微妙だけど後で考える
		AbstBuffer(const AbstBuffer& ab) {
			_type = ab._type;
			_pSrc = ab._pSrc;
			_size = ab._size;
		}
		//! initialize by const-pointer
		AbstBuffer(const void* src, size_t sz): _type(Type::ConstPtr), _size(sz), _pSrc(reinterpret_cast<const T*>(src)) {}
		//! initialize by movable-vector
		AbstBuffer(Buff&& buff): _type(Type::Movable), _buffM(&buff), _size(buff.size()) {}
		//! initialize by const-vector
		AbstBuffer(const Buff& buff): _type(Type::Const), _buffC(&buff), _size(buff.size()) {}

		void setTo(Buff& dst) {
			switch(_type) {
				case Type::ConstPtr:
					dst.assign(_pSrc, _pSrc+_size);
					break;
				case Type::Movable:
					dst = std::move(*_buffM);
					_invalidate();
					break;
				case Type::Const:
					dst = *_buffC;
					break;
				default:
					assert(false);
					break;
			}
		}
		Buff moveTo() {
			switch(_type) {
				case Type::ConstPtr: return Buff(_pSrc, _pSrc+_size);
				case Type::Movable: return std::move(*_buffM);
				case Type::Const: return *_buffC;
				default: assert(false);
			}
		}

		size_t getSize() const {
			return _size;
		}
		const T* getPtr() const {
			if(_type == Type::ConstPtr)
				return _pSrc;
			return &(*_buffC)[0];
		}
	};

	size_t GetLength(const char* str);
	size_t GetLength(const char16_t* str);
	size_t GetLength(const char32_t* str);
	template <class T>
	class AbstString : public AbstBuffer<T, std::basic_string<T>> {
		using base_type = AbstBuffer<T, std::basic_string<T>>;
		using Str = std::basic_string<T>;
		public:
			// 文字数カウント機能を追加
			AbstString(const T* src): base_type(src, GetLength(src)) {}
			AbstString(const T* src, size_t len): base_type(src, len) {}
			AbstString(Str&& str): base_type(std::move(str)) {}
			AbstString(const Str& str): base_type(str) {}
	};
	using c8Str = AbstString<char>;
	using c16Str = AbstString<char16_t>;
	using c32Str = AbstString<char32_t>;
	using c8Buff = AbstBuffer<char>;
	using c16Buff = AbstBuffer<char16_t>;
	using c32Buff = AbstBuffer<char32_t>;

	using ByteBuff = std::vector<uint8_t>;
	using U16Buff = std::vector<uint16_t>;
	using FloatBuff = std::vector<float>;
	using AB_Byte = AbstBuffer<uint8_t>;
	using AB_U16 = AbstBuffer<uint16_t>;
	using AB_Float = AbstBuffer<float>;
}
<|endoftext|>