<commit_before>/************************************************
 *  static_assoc.hpp
 *  bptree
 *
 *  Copyright (c) 2017, Chi-En Wu
 *  Distributed under MIT License
 ************************************************/

#ifndef BPTREE_INTERNAL_STATIC_ASSOC_HPP_
#define BPTREE_INTERNAL_STATIC_ASSOC_HPP_

#include <cstddef>

#include "./static_vector.hpp"

namespace bptree {

namespace internal {

/************************************************
 * Declaration: class static_assoc<T, U, N>
 ************************************************/

template <typename ValueTraits, bool Unique, std::size_t N>
class static_assoc
  : public ValueTraits,
    private ValueTraits::value_compare {
 private:  // Private Type(s)
    using value_traits = ValueTraits;
    using underlying_type = static_vector<typename value_traits::value_type, N>;

 public:  // Public Type(s)
    using key_type = typename value_traits::key_type;
    using value_type = typename value_traits::value_type;
    using key_compare = typename value_traits::key_compare;
    using value_compare = typename value_traits::value_compare;

    using reference = typename underlying_type::reference;
    using const_reference = typename underlying_type::const_reference;
    using pointer = typename underlying_type::pointer;
    using const_pointer = typename underlying_type::const_pointer;
    using size_type = typename underlying_type::size_type;
    using difference_type = typename underlying_type::difference_type;

    using iterator = typename underlying_type::iterator;
    using const_iterator = typename underlying_type::const_iterator;
    using reverse_iterator = typename underlying_type::reverse_iterator;
    using const_reverse_iterator = typename underlying_type::const_reverse_iterator;

 public:  // Public Method(s)
    static_assoc();
    explicit static_assoc(key_compare comp);
    template <typename InputIt>
    static_assoc(InputIt first, InputIt last, key_compare const& comp = key_compare());
    static_assoc(std::initializer_list<value_type> il, key_compare const& comp = key_compare());
    static_assoc(static_assoc const&) = default;
    static_assoc(static_assoc&&) = default;

    static_assoc& operator=(std::initializer_list<value_type> il);

    bool empty() const noexcept;
    bool full() const noexcept;
    size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;
    constexpr size_type capacity() const noexcept;

    iterator begin() noexcept;
    const_iterator begin() const noexcept;
    const_iterator cbegin() const noexcept;
    iterator end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cend() const noexcept;
    reverse_iterator rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    reverse_iterator rend() noexcept;
    const_reverse_iterator rend() const noexcept;
    const_reverse_iterator crend() const noexcept;

    key_compare key_comp() const;
    value_compare value_comp() const;

 private:  // Private Method(s)
    bool is_equal(value_type const& x, value_type const& y);

 private:  // Private Property(ies)
    underlying_type values_;
};

/************************************************
 * Implementation: class static_assoc<T, U, N>
 ************************************************/

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc()
  : static_assoc(key_compare()) {
    // do nothing
}

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc(key_compare comp)
  : value_compare(comp), values_() {
    // do nothing
}

template <typename T, bool U, std::size_t N>
template <typename InputIt>
static_assoc<T, U, N>::static_assoc(InputIt first, InputIt last, key_compare const& comp)
  : static_assoc(comp) {
    while (first != last) {
        auto pos = std::upper_bound(values_.cbegin(), values_.cend(), *first, value_comp());
        if (!U || pos == begin() || !is_equal(*(pos - 1), *first)) {
            values_.insert(pos, *first);
        }

        ++first;
    }
}

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc(std::initializer_list<value_type> il,
                                           key_compare const& comp)
  : static_assoc(il.begin(), il.end(), comp) {
    // do nothing
}

template <typename T, bool U, std::size_t N>
static_assoc<T, U, N>&
static_assoc<T, U, N>::operator=(std::initializer_list<value_type> il) {
    values_.clear();

    for (auto& value : il) {
        auto pos = std::upper_bound(values_.cbegin(), values_.cend(), value, value_comp());
        if (!U || pos == begin() || !is_equal(*(pos - 1), value)) {
            values_.insert(pos, value);
        }
    }

    return *this;
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::empty() const noexcept {
    return values_.empty();
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::full() const noexcept {
    return values_.full();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::size() const noexcept {
    return values_.size();
}

template <typename T, bool U, std::size_t N>
inline constexpr typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::max_size() const noexcept {
    return values_.max_size();
}

template <typename T, bool U, std::size_t N>
inline constexpr typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::capacity() const noexcept {
    return values_.capacity();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::iterator
static_assoc<T, U, N>::begin() noexcept {
    return values_.begin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::begin() const noexcept {
    return cbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::cbegin() const noexcept {
    return values_.cbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::iterator
static_assoc<T, U, N>::end() noexcept {
    return values_.end();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::end() const noexcept {
    return cend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::cend() const noexcept {
    return values_.cend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::reverse_iterator
static_assoc<T, U, N>::rbegin() noexcept {
    return values_.rbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::rbegin() const noexcept {
    return crbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::crbegin() const noexcept {
    return values_.crbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::reverse_iterator
static_assoc<T, U, N>::rend() noexcept {
    return values_.rend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::rend() const noexcept {
    return crend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::crend() const noexcept {
    return values_.crend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::key_compare
static_assoc<T, U, N>::key_comp() const {
    return key_compare(*this);
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::value_compare
static_assoc<T, U, N>::value_comp() const {
    return value_compare(*this);
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::is_equal(value_type const& x, value_type const& y) {
    return !value_compare::operator()(x, y) && !value_compare::operator()(y, x);
}

}  // namespace internal

}  // namespace bptree

#endif  // BPTREE_INTERNAL_STATIC_ASSOC_HPP_
<commit_msg>:sparkles: Add `internal::static_assoc<>::clear()`<commit_after>/************************************************
 *  static_assoc.hpp
 *  bptree
 *
 *  Copyright (c) 2017, Chi-En Wu
 *  Distributed under MIT License
 ************************************************/

#ifndef BPTREE_INTERNAL_STATIC_ASSOC_HPP_
#define BPTREE_INTERNAL_STATIC_ASSOC_HPP_

#include <cstddef>

#include "./static_vector.hpp"

namespace bptree {

namespace internal {

/************************************************
 * Declaration: class static_assoc<T, U, N>
 ************************************************/

template <typename ValueTraits, bool Unique, std::size_t N>
class static_assoc
  : public ValueTraits,
    private ValueTraits::value_compare {
 private:  // Private Type(s)
    using value_traits = ValueTraits;
    using underlying_type = static_vector<typename value_traits::value_type, N>;

 public:  // Public Type(s)
    using key_type = typename value_traits::key_type;
    using value_type = typename value_traits::value_type;
    using key_compare = typename value_traits::key_compare;
    using value_compare = typename value_traits::value_compare;

    using reference = typename underlying_type::reference;
    using const_reference = typename underlying_type::const_reference;
    using pointer = typename underlying_type::pointer;
    using const_pointer = typename underlying_type::const_pointer;
    using size_type = typename underlying_type::size_type;
    using difference_type = typename underlying_type::difference_type;

    using iterator = typename underlying_type::iterator;
    using const_iterator = typename underlying_type::const_iterator;
    using reverse_iterator = typename underlying_type::reverse_iterator;
    using const_reverse_iterator = typename underlying_type::const_reverse_iterator;

 public:  // Public Method(s)
    static_assoc();
    explicit static_assoc(key_compare comp);
    template <typename InputIt>
    static_assoc(InputIt first, InputIt last, key_compare const& comp = key_compare());
    static_assoc(std::initializer_list<value_type> il, key_compare const& comp = key_compare());
    static_assoc(static_assoc const&) = default;
    static_assoc(static_assoc&&) = default;

    static_assoc& operator=(std::initializer_list<value_type> il);

    void clear() noexcept;

    bool empty() const noexcept;
    bool full() const noexcept;
    size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;
    constexpr size_type capacity() const noexcept;

    iterator begin() noexcept;
    const_iterator begin() const noexcept;
    const_iterator cbegin() const noexcept;
    iterator end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cend() const noexcept;
    reverse_iterator rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    reverse_iterator rend() noexcept;
    const_reverse_iterator rend() const noexcept;
    const_reverse_iterator crend() const noexcept;

    key_compare key_comp() const;
    value_compare value_comp() const;

 private:  // Private Method(s)
    bool is_equal(value_type const& x, value_type const& y);

 private:  // Private Property(ies)
    underlying_type values_;
};

/************************************************
 * Implementation: class static_assoc<T, U, N>
 ************************************************/

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc()
  : static_assoc(key_compare()) {
    // do nothing
}

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc(key_compare comp)
  : value_compare(comp), values_() {
    // do nothing
}

template <typename T, bool U, std::size_t N>
template <typename InputIt>
static_assoc<T, U, N>::static_assoc(InputIt first, InputIt last, key_compare const& comp)
  : static_assoc(comp) {
    while (first != last) {
        auto pos = std::upper_bound(values_.cbegin(), values_.cend(), *first, value_comp());
        if (!U || pos == begin() || !is_equal(*(pos - 1), *first)) {
            values_.insert(pos, *first);
        }

        ++first;
    }
}

template <typename T, bool U, std::size_t N>
inline static_assoc<T, U, N>::static_assoc(std::initializer_list<value_type> il,
                                           key_compare const& comp)
  : static_assoc(il.begin(), il.end(), comp) {
    // do nothing
}

template <typename T, bool U, std::size_t N>
static_assoc<T, U, N>&
static_assoc<T, U, N>::operator=(std::initializer_list<value_type> il) {
    clear();

    for (auto& value : il) {
        auto pos = std::upper_bound(values_.cbegin(), values_.cend(), value, value_comp());
        if (!U || pos == begin() || !is_equal(*(pos - 1), value)) {
            values_.insert(pos, value);
        }
    }

    return *this;
}

template <typename T, bool U, std::size_t N>
inline void static_assoc<T, U, N>::clear() noexcept {
    values_.clear();
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::empty() const noexcept {
    return values_.empty();
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::full() const noexcept {
    return values_.full();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::size() const noexcept {
    return values_.size();
}

template <typename T, bool U, std::size_t N>
inline constexpr typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::max_size() const noexcept {
    return values_.max_size();
}

template <typename T, bool U, std::size_t N>
inline constexpr typename static_assoc<T, U, N>::size_type
static_assoc<T, U, N>::capacity() const noexcept {
    return values_.capacity();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::iterator
static_assoc<T, U, N>::begin() noexcept {
    return values_.begin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::begin() const noexcept {
    return cbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::cbegin() const noexcept {
    return values_.cbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::iterator
static_assoc<T, U, N>::end() noexcept {
    return values_.end();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::end() const noexcept {
    return cend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_iterator
static_assoc<T, U, N>::cend() const noexcept {
    return values_.cend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::reverse_iterator
static_assoc<T, U, N>::rbegin() noexcept {
    return values_.rbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::rbegin() const noexcept {
    return crbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::crbegin() const noexcept {
    return values_.crbegin();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::reverse_iterator
static_assoc<T, U, N>::rend() noexcept {
    return values_.rend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::rend() const noexcept {
    return crend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::const_reverse_iterator
static_assoc<T, U, N>::crend() const noexcept {
    return values_.crend();
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::key_compare
static_assoc<T, U, N>::key_comp() const {
    return key_compare(*this);
}

template <typename T, bool U, std::size_t N>
inline typename static_assoc<T, U, N>::value_compare
static_assoc<T, U, N>::value_comp() const {
    return value_compare(*this);
}

template <typename T, bool U, std::size_t N>
inline bool static_assoc<T, U, N>::is_equal(value_type const& x, value_type const& y) {
    return !value_compare::operator()(x, y) && !value_compare::operator()(y, x);
}

}  // namespace internal

}  // namespace bptree

#endif  // BPTREE_INTERNAL_STATIC_ASSOC_HPP_
<|endoftext|>


<commit_before><commit_msg>Replace ~CreateSessionDescriptionRequest CHECK with DLOG. During shutdown, it is not guaranteed that the tasks posted in OnSuccess and onFailure will complete. To avoid the CHECK during shutdown, it is replaced by DLOG.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MABPreparedStatement.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:29:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_
#define _CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_

#ifndef _CONNECTIVITY_FILE_OPREPAREDSTATEMENT_HXX_
#include "file/FPreparedStatement.hxx"
#endif

namespace connectivity
{
    namespace mozaddressbook
    {
        class OConnection;
        class OMozabPreparedStatement : public file::OPreparedStatement
        {
        protected:
            virtual file::OResultSet* createResultSet();
            // here we create a SQL analyzer which doesn't support any restrictions
            // these are already done by the server side
            virtual file::OSQLAnalyzer* createAnalyzer();
        public:
            //  DECLARE_CTY_DEFAULTS(file::OStatement);
            OMozabPreparedStatement( file::OConnection* _pConnection ) : file::OPreparedStatement( _pConnection ){}
            DECLARE_SERVICE_INFO();
        };
    }
}

#endif //_CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.7.372); FILE MERGED 2008/04/01 10:53:40 thb 1.7.372.2: #i85898# Stripping all external header guards 2008/03/28 15:24:31 rt 1.7.372.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MABPreparedStatement.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_
#define _CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_

#include "file/FPreparedStatement.hxx"

namespace connectivity
{
    namespace mozaddressbook
    {
        class OConnection;
        class OMozabPreparedStatement : public file::OPreparedStatement
        {
        protected:
            virtual file::OResultSet* createResultSet();
            // here we create a SQL analyzer which doesn't support any restrictions
            // these are already done by the server side
            virtual file::OSQLAnalyzer* createAnalyzer();
        public:
            //  DECLARE_CTY_DEFAULTS(file::OStatement);
            OMozabPreparedStatement( file::OConnection* _pConnection ) : file::OPreparedStatement( _pConnection ){}
            DECLARE_SERVICE_INFO();
        };
    }
}

#endif //_CONNECTIVITY_MAB_PREPAREDSTATEMENT_HXX_

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	ifstream infile(fileName) ;
	string line;

	while(getline(infile, line)) {
		istringstream iss(line);
		int n;
		iss >> n;
		insert(listSize, n);
	}

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
		int remainder = value%theInt;
cout << "value: " << value << ", Remainder: " << remainder << ", listSize: " << listSize << ", i: " << i << endl;

        	if (remainder == 0 && value > theInt) {
			erase(i);
        		i--;
		}
output();
	}

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
        	insert(0, value);
	}

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<commit_msg>first 2 working<commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	ifstream infile(fileName) ;
	string line;

	while(getline(infile, line)) {
		istringstream iss(line);
		int n;
		iss >> n;
		insert(listSize, n);
	}

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
		int remainder = value%theInt;

        	if (remainder == 0 && value > theInt) {
			erase(i);
        		i--;
		}
	}

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
        	insert(0, value);
	}

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<|endoftext|>


<commit_before>//
// Copyright (c) 2013-2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef RJ_GAME_EDITOR_EDITOR_HPP
#define RJ_GAME_EDITOR_EDITOR_HPP

#include "background_editor.hpp"
#include "editor_entity.hpp"
#include "itembar.hpp"
#include "mouse.hpp"
#include "settingsbar.hpp"
#include <rectojump/game/components/platform.hpp>
#include <rectojump/game/camera.hpp>
#include <rectojump/game/world.hpp>

namespace rj
{
	template<typename Game_Handler, typename Game>
	class editor
	{
	public:
		using gh_type = Game_Handler;

		Game_Handler& m_gamehandler;
		Game& m_game;
		world<Game_Handler>& m_gameworld;
		entity_handler& m_entityhandler;
		level_manager& m_levelmgr;

		camera m_editarea_camera;
		camera m_itembar_camera;
		camera m_settingsbar_camera;

		editor_mouse m_mouse;
		background_editor<editor> m_background{*this};
		itembar<Game_Handler> m_itembar;
		settingsbar<editor> m_settingsbar;

	public:
		editor(Game_Handler& gh) :
			m_gamehandler{gh},
			m_game{gh.get_game()},
			m_gameworld{m_game.get_world()},
			m_entityhandler{m_gameworld.get_entityhandler()},
			m_levelmgr{gh.get_levelmgr()},
			m_editarea_camera{m_gamehandler.get_gamewindow()},
			m_itembar_camera{m_gamehandler.get_gamewindow()},
			m_settingsbar_camera{m_gamehandler.get_gamewindow()},
			m_mouse{gh.get_render()},
			m_itembar{gh, {settings::get_window_size<vec2f>().x, 100.f}},
			m_settingsbar{*this, {300.f, settings::get_window_size<vec2f>().y - m_itembar.get_size().y}}
		{this->init();}

		void update(dur duration)
		{
			// edit area
			m_editarea_camera.set_changes();
			m_mouse.update(duration);

			// itembar
			m_itembar_camera.set_changes();
			m_itembar.update(duration);

			// settingsbar
			m_settingsbar_camera.set_changes();
			m_settingsbar.update(duration);
		}

		void render()
		{
			// edit area
			m_editarea_camera.set_changes();
			m_entityhandler.render();
			m_mouse.render();

			// itembar
			m_itembar_camera.set_changes();
			m_itembar.render();

			// settingsbar
			m_settingsbar_camera.set_changes();
			m_settingsbar.render();
		}

		void handle_save()
		{
			level_data lv_data;
			for(auto& a : m_entityhandler)
			{
				auto ent(this->to_editor_entity(a));
				lv_data.add_entity(ent->get_figure(), entity_propertie::solid, ent->pos());

			}

			level_info lv_info{"Test", "ABC"};
			music_data lv_music{'M', 'U', 'S', 'I', 'C'};
			level_packer<packer_mode::pack> lv_packer{lv_music, lv_data, lv_info};

			m_levelmgr.save_level(lv_packer, "TESTLV0");
		}

		void handle_load()
		{

		}

		void on_activate()
		{
			m_background.reset();
		}

		auto get_gamehandler() noexcept
		-> decltype(m_gamehandler)&
		{return m_gamehandler;}

	private:
		void init()
		{
			// change mousetexture on itembar-item click
			m_itembar.on_item_click =
			[this](ui::base_btn_ptr& b){m_mouse.set_texture(b->get_texture());};

			// init mouse texture
			m_mouse.set_texture(&m_itembar.get_current_texture());

			this->init_input();
			this->init_cameras();
		}

		void init_input()
		{
			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos){this->on_mouse_left(pos);}, btn::Left);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos){this->on_mouse_right(pos);}, btn::Right);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos)
			{m_editarea_camera.move({settings::get_editor_scroll_step(), 0.f});}, wheel::down);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos)
			{
				if(m_editarea_camera.get_center().x >= m_editarea_camera.get_startcenter().x)
					m_editarea_camera.move({-settings::get_editor_scroll_step(), 0.f});
			}, wheel::up);
		}

		void init_cameras() noexcept
		{
			auto window_size(settings::get_window_size<vec2f>());
			auto& itembar_size(m_itembar.get_size());
			auto& settingsbar_size(m_settingsbar.get_size());

			float itembar_top{(window_size.y - itembar_size.y) / window_size.y};
			float itembar_height{itembar_size.y / window_size.y};
			float editarea_height{(window_size.y - itembar_size.y) / window_size.y};

			sf::View editarea_view{vec2f{window_size.x, window_size.y - itembar_size.y} / 2.f, {window_size.x, window_size.y - itembar_size.y}};
			editarea_view.setViewport({0.f, 0.f, 1.f ,editarea_height});
			m_editarea_camera.set_view(editarea_view);

			sf::View itembar_view{vec2f{window_size.x, itembar_size.y} / 2.f, {window_size.x, itembar_size.y}};
			itembar_view.setViewport({0.f, itembar_top, 1.f, itembar_height});
			m_itembar_camera.set_view(itembar_view);

			sf::View settingsbar_view{vec2f{settingsbar_size.x, window_size.y} / 2.f, {settingsbar_size.x, window_size.y}};
			settingsbar_view.setViewport({(window_size.x - settingsbar_size.x) / window_size.x, 0.f, settingsbar_size.x / window_size.x, 1.f});
			m_settingsbar_camera.set_view(settingsbar_view);
		}

		void on_mouse_left(const vec2f&)
		{
			// check the itembar and settingsbar bounds
			auto itembar_mouse_bounds(bounds_from_vec(m_itembar_camera.get_mapped_mousepos()));
			auto settingsbar_mouse_bounds(bounds_from_vec(m_settingsbar_camera.get_mapped_mousepos()));
			if(itembar_mouse_bounds.intersects(m_itembar.get_bounds()) ||
			   settingsbar_mouse_bounds.intersects(m_settingsbar.get_bounds()))
				return;

			float f{48.f};
			vec2f new_pos{round_to(m_editarea_camera.get_mapped_mousepos().x, f), round_to(m_editarea_camera.get_mapped_mousepos().y, f)};

			// check if entity exists at this pos
			auto iter(m_entityhandler.exists_entity_at(m_editarea_camera.get_mapped_mousepos()));
			if(iter != std::end(m_entityhandler))
			{
				auto ptr(this->to_editor_entity(*iter));
				m_mouse.set_texture(ptr->get_texture());
				m_itembar.select(ptr->get_figure());
				return;
			}

			// set entity at pos
			if(m_mouse.get_texture())
			{
				auto ptr(m_gameworld.template create_entity<editor_entity>(new_pos));
				ptr->render_object().setTexture(m_mouse.get_texture());
				ptr->set_figure(m_itembar.get_current_figure());
			}
		}

		void on_mouse_right(const vec2f&)
		{
			m_itembar.deselect_all();
			m_mouse.clear();

			auto iter(m_entityhandler.exists_entity_at(m_editarea_camera.get_mapped_mousepos()));
			if(iter != std::end(m_entityhandler))
				m_entityhandler.delete_entity(iter);
		}

		template<typename Ent_Ptr>
		auto to_editor_entity(const Ent_Ptr& ptr)
		-> decltype(std::static_pointer_cast<editor_entity>(ptr))
		{return std::static_pointer_cast<editor_entity>(ptr);}
	};
}

#endif // RJ_GAME_EDITOR_EDITOR_HPP
<commit_msg>editor: fixed testing public -> private<commit_after>//
// Copyright (c) 2013-2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef RJ_GAME_EDITOR_EDITOR_HPP
#define RJ_GAME_EDITOR_EDITOR_HPP

#include "background_editor.hpp"
#include "editor_entity.hpp"
#include "itembar.hpp"
#include "mouse.hpp"
#include "settingsbar.hpp"
#include <rectojump/game/components/platform.hpp>
#include <rectojump/game/camera.hpp>
#include <rectojump/game/world.hpp>

namespace rj
{
	template<typename Game_Handler, typename Game>
	class editor
	{
	public:
		using gh_type = Game_Handler;

	private:
		Game_Handler& m_gamehandler;
		Game& m_game;
		world<Game_Handler>& m_gameworld;
		entity_handler& m_entityhandler;
		level_manager& m_levelmgr;

		camera m_editarea_camera;
		camera m_itembar_camera;
		camera m_settingsbar_camera;

		editor_mouse m_mouse;
		background_editor<editor> m_background{*this};
		itembar<Game_Handler> m_itembar;
		settingsbar<editor> m_settingsbar;

	public:
		editor(Game_Handler& gh) :
			m_gamehandler{gh},
			m_game{gh.get_game()},
			m_gameworld{m_game.get_world()},
			m_entityhandler{m_gameworld.get_entityhandler()},
			m_levelmgr{gh.get_levelmgr()},
			m_editarea_camera{m_gamehandler.get_gamewindow()},
			m_itembar_camera{m_gamehandler.get_gamewindow()},
			m_settingsbar_camera{m_gamehandler.get_gamewindow()},
			m_mouse{gh.get_render()},
			m_itembar{gh, {settings::get_window_size<vec2f>().x, 100.f}},
			m_settingsbar{*this, {300.f, settings::get_window_size<vec2f>().y - m_itembar.get_size().y}}
		{this->init();}

		void update(dur duration)
		{
			// edit area
			m_editarea_camera.set_changes();
			m_mouse.update(duration);

			// itembar
			m_itembar_camera.set_changes();
			m_itembar.update(duration);

			// settingsbar
			m_settingsbar_camera.set_changes();
			m_settingsbar.update(duration);
		}

		void render()
		{
			// edit area
			m_editarea_camera.set_changes();
			m_entityhandler.render();
			m_mouse.render();

			// itembar
			m_itembar_camera.set_changes();
			m_itembar.render();

			// settingsbar
			m_settingsbar_camera.set_changes();
			m_settingsbar.render();
		}

		void handle_save(const std::string& level_name)
		{
			level_data lv_data;
			for(auto& a : m_entityhandler)
			{
				auto ent(this->to_editor_entity(a));
				lv_data.add_entity(ent->get_figure(), entity_propertie::solid, ent->pos());

			}

			level_info lv_info{"Test", "ABC"};
			music_data lv_music{'M', 'U', 'S', 'I', 'C'};
			level_packer<packer_mode::pack> lv_packer{lv_music, lv_data, lv_info};

			m_levelmgr.save_level(lv_packer, level_name);
		}

		void handle_load(const std::string& level_name)
		{

		}

		void on_activate()
		{
			m_background.reset();
		}

		auto get_gamehandler() noexcept
		-> decltype(m_gamehandler)&
		{return m_gamehandler;}

	private:
		void init()
		{
			// change mousetexture on itembar-item click
			m_itembar.on_item_click =
			[this](ui::base_btn_ptr& b){m_mouse.set_texture(b->get_texture());};

			// init mouse texture
			m_mouse.set_texture(&m_itembar.get_current_texture());

			this->init_input();
			this->init_cameras();
		}

		void init_input()
		{
			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos){this->on_mouse_left(pos);}, btn::Left);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos){this->on_mouse_right(pos);}, btn::Right);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos)
			{m_editarea_camera.move({settings::get_editor_scroll_step(), 0.f});}, wheel::down);

			m_gamehandler.template add_input<state::editor>(
			[this](const vec2f& pos)
			{
				if(m_editarea_camera.get_center().x >= m_editarea_camera.get_startcenter().x)
					m_editarea_camera.move({-settings::get_editor_scroll_step(), 0.f});
			}, wheel::up);
		}

		void init_cameras() noexcept
		{
			auto window_size(settings::get_window_size<vec2f>());
			auto& itembar_size(m_itembar.get_size());
			auto& settingsbar_size(m_settingsbar.get_size());

			float itembar_top{(window_size.y - itembar_size.y) / window_size.y};
			float itembar_height{itembar_size.y / window_size.y};
			float editarea_height{(window_size.y - itembar_size.y) / window_size.y};

			sf::View editarea_view{vec2f{window_size.x, window_size.y - itembar_size.y} / 2.f, {window_size.x, window_size.y - itembar_size.y}};
			editarea_view.setViewport({0.f, 0.f, 1.f ,editarea_height});
			m_editarea_camera.set_view(editarea_view);

			sf::View itembar_view{vec2f{window_size.x, itembar_size.y} / 2.f, {window_size.x, itembar_size.y}};
			itembar_view.setViewport({0.f, itembar_top, 1.f, itembar_height});
			m_itembar_camera.set_view(itembar_view);

			sf::View settingsbar_view{vec2f{settingsbar_size.x, window_size.y} / 2.f, {settingsbar_size.x, window_size.y}};
			settingsbar_view.setViewport({(window_size.x - settingsbar_size.x) / window_size.x, 0.f, settingsbar_size.x / window_size.x, 1.f});
			m_settingsbar_camera.set_view(settingsbar_view);
		}

		void on_mouse_left(const vec2f&)
		{
			// check the itembar and settingsbar bounds
			auto itembar_mouse_bounds(bounds_from_vec(m_itembar_camera.get_mapped_mousepos()));
			auto settingsbar_mouse_bounds(bounds_from_vec(m_settingsbar_camera.get_mapped_mousepos()));
			if(itembar_mouse_bounds.intersects(m_itembar.get_bounds()) ||
			   settingsbar_mouse_bounds.intersects(m_settingsbar.get_bounds()))
				return;

			float f{48.f};
			vec2f new_pos{round_to(m_editarea_camera.get_mapped_mousepos().x, f), round_to(m_editarea_camera.get_mapped_mousepos().y, f)};

			// check if entity exists at this pos
			auto iter(m_entityhandler.exists_entity_at(m_editarea_camera.get_mapped_mousepos()));
			if(iter != std::end(m_entityhandler))
			{
				auto ptr(this->to_editor_entity(*iter));
				m_mouse.set_texture(ptr->get_texture());
				m_itembar.select(ptr->get_figure());
				return;
			}

			// set entity at pos
			if(m_mouse.get_texture())
			{
				auto ptr(m_gameworld.template create_entity<editor_entity>(new_pos));
				ptr->render_object().setTexture(m_mouse.get_texture());
				ptr->set_figure(m_itembar.get_current_figure());
			}
		}

		void on_mouse_right(const vec2f&)
		{
			m_itembar.deselect_all();
			m_mouse.clear();

			auto iter(m_entityhandler.exists_entity_at(m_editarea_camera.get_mapped_mousepos()));
			if(iter != std::end(m_entityhandler))
				m_entityhandler.delete_entity(iter);
		}

		template<typename Ent_Ptr>
		auto to_editor_entity(const Ent_Ptr& ptr)
		-> decltype(std::static_pointer_cast<editor_entity>(ptr))
		{return std::static_pointer_cast<editor_entity>(ptr);}
	};
}

#endif // RJ_GAME_EDITOR_EDITOR_HPP
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/kernels/data/tf_record_dataset_op.h"

#include "tensorflow/core/common_runtime/metrics.h"
#include "tensorflow/core/framework/partial_tensor_shape.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/kernels/data/name_utils.h"
#include "tensorflow/core/lib/io/buffered_inputstream.h"
#include "tensorflow/core/lib/io/inputbuffer.h"
#include "tensorflow/core/lib/io/random_inputstream.h"
#include "tensorflow/core/lib/io/record_reader.h"
#include "tensorflow/core/lib/io/zlib_compression_options.h"
#include "tensorflow/core/lib/io/zlib_inputstream.h"

namespace tensorflow {
namespace data {

// See documentation in ../../ops/dataset_ops.cc for a high-level
// description of the following ops.

/* static */ constexpr const char* const TFRecordDatasetOp::kDatasetType;
/* static */ constexpr const char* const TFRecordDatasetOp::kFileNames;
/* static */ constexpr const char* const TFRecordDatasetOp::kCompressionType;
/* static */ constexpr const char* const TFRecordDatasetOp::kBufferSize;

constexpr char kCurrentFileIndex[] = "current_file_index";
constexpr char kOffset[] = "offset";

class TFRecordDatasetOp::Dataset : public DatasetBase {
 public:
  explicit Dataset(OpKernelContext* ctx, std::vector<string> filenames,
                   const string& compression_type, int64 buffer_size)
      : DatasetBase(DatasetContext(ctx)),
        filenames_(std::move(filenames)),
        compression_type_(compression_type),
        options_(io::RecordReaderOptions::CreateRecordReaderOptions(
            compression_type)) {
    if (buffer_size > 0) {
      options_.buffer_size = buffer_size;
    }
  }

  std::unique_ptr<IteratorBase> MakeIteratorInternal(
      const string& prefix) const override {
    return absl::make_unique<Iterator>(Iterator::Params{
        this, name_utils::IteratorPrefix(kDatasetType, prefix)});
  }

  const DataTypeVector& output_dtypes() const override {
    static DataTypeVector* dtypes = new DataTypeVector({DT_STRING});
    return *dtypes;
  }

  const std::vector<PartialTensorShape>& output_shapes() const override {
    static std::vector<PartialTensorShape>* shapes =
        new std::vector<PartialTensorShape>({{}});
    return *shapes;
  }

  string DebugString() const override {
    return name_utils::DatasetDebugString(kDatasetType);
  }

  Status CheckExternalState() const override { return Status::OK(); }

 protected:
  Status AsGraphDefInternal(SerializationContext* ctx,
                            DatasetGraphDefBuilder* b,
                            Node** output) const override {
    Node* filenames = nullptr;
    TF_RETURN_IF_ERROR(b->AddVector(filenames_, &filenames));
    Node* compression_type = nullptr;
    TF_RETURN_IF_ERROR(b->AddScalar(compression_type_, &compression_type));
    Node* buffer_size = nullptr;
    TF_RETURN_IF_ERROR(b->AddScalar(options_.buffer_size, &buffer_size));
    TF_RETURN_IF_ERROR(b->AddDataset(
        this, {filenames, compression_type, buffer_size}, output));
    return Status::OK();
  }

 private:
  class Iterator : public DatasetIterator<Dataset> {
   public:
    explicit Iterator(const Params& params)
        : DatasetIterator<Dataset>(params) {}

    Status GetNextInternal(IteratorContext* ctx,
                           std::vector<Tensor>* out_tensors,
                           bool* end_of_sequence) override {
      out_tensors->reserve(1);
      mutex_lock l(mu_);
      do {
        // We are currently processing a file, so try to read the next record.
        if (reader_) {
          out_tensors->emplace_back(ctx->allocator({}), DT_STRING,
                                    TensorShape({}));
          Status s =
              reader_->ReadRecord(&out_tensors->back().scalar<tstring>()());
          if (s.ok()) {
            metrics::RecordTFDataBytesRead(
                kDatasetType, out_tensors->back().scalar<tstring>()().size());
            *end_of_sequence = false;
            return Status::OK();
          }
          out_tensors->pop_back();
          if (!errors::IsOutOfRange(s)) {
            // In case of other errors e.g., DataLoss, we still move forward
            // the file index so that it works with ignore_errors.
            // Otherwise the same file will repeat.
            ResetStreamsLocked();
            ++current_file_index_;
            return s;
          }

          // We have reached the end of the current file, so maybe move on to
          // next file.
          ResetStreamsLocked();
          ++current_file_index_;
        }

        // Iteration ends when there are no more files to process.
        if (current_file_index_ == dataset()->filenames_.size()) {
          *end_of_sequence = true;
          return Status::OK();
        }

        TF_RETURN_IF_ERROR(SetupStreamsLocked(ctx->env()));
      } while (true);
    }

   protected:
    std::shared_ptr<model::Node> CreateNode(
        IteratorContext* ctx, model::Node::Args args) const override {
      return model::MakeSourceNode(std::move(args));
    }

    Status SaveInternal(IteratorStateWriter* writer) override {
      mutex_lock l(mu_);
      TF_RETURN_IF_ERROR(writer->WriteScalar(full_name(kCurrentFileIndex),
                                             current_file_index_));

      if (reader_) {
        TF_RETURN_IF_ERROR(
            writer->WriteScalar(full_name(kOffset), reader_->TellOffset()));
      }
      return Status::OK();
    }

    Status RestoreInternal(IteratorContext* ctx,
                           IteratorStateReader* reader) override {
      mutex_lock l(mu_);
      ResetStreamsLocked();
      int64 current_file_index;
      TF_RETURN_IF_ERROR(reader->ReadScalar(full_name(kCurrentFileIndex),
                                            &current_file_index));
      current_file_index_ = size_t(current_file_index);
      if (reader->Contains(full_name(kOffset))) {
        int64 offset;
        TF_RETURN_IF_ERROR(reader->ReadScalar(full_name(kOffset), &offset));
        TF_RETURN_IF_ERROR(SetupStreamsLocked(ctx->env()));
        TF_RETURN_IF_ERROR(reader_->SeekOffset(offset));
      }
      return Status::OK();
    }

   private:
    // Sets up reader streams to read from the file at `current_file_index_`.
    Status SetupStreamsLocked(Env* env) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
      if (current_file_index_ >= dataset()->filenames_.size()) {
        return errors::InvalidArgument(
            "current_file_index_:", current_file_index_,
            " >= filenames_.size():", dataset()->filenames_.size());
      }

      // Actually move on to next file.
      const string& next_filename = dataset()->filenames_[current_file_index_];
      TF_RETURN_IF_ERROR(env->NewRandomAccessFile(next_filename, &file_));
      reader_ = absl::make_unique<io::SequentialRecordReader>(
          file_.get(), dataset()->options_);
      return Status::OK();
    }

    // Resets all reader streams.
    void ResetStreamsLocked() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
      reader_.reset();
      file_.reset();
    }

    mutex mu_;
    size_t current_file_index_ GUARDED_BY(mu_) = 0;

    // `reader_` will borrow the object that `file_` points to, so
    // we must destroy `reader_` before `file_`.
    std::unique_ptr<RandomAccessFile> file_ GUARDED_BY(mu_);
    std::unique_ptr<io::SequentialRecordReader> reader_ GUARDED_BY(mu_);
  };

  const std::vector<string> filenames_;
  const tstring compression_type_;
  io::RecordReaderOptions options_;
};

TFRecordDatasetOp::TFRecordDatasetOp(OpKernelConstruction* ctx)
    : DatasetOpKernel(ctx) {}

void TFRecordDatasetOp::MakeDataset(OpKernelContext* ctx,
                                    DatasetBase** output) {
  const Tensor* filenames_tensor;
  OP_REQUIRES_OK(ctx, ctx->input(kFileNames, &filenames_tensor));
  OP_REQUIRES(
      ctx, filenames_tensor->dims() <= 1,
      errors::InvalidArgument("`filenames` must be a scalar or a vector."));

  std::vector<string> filenames;
  filenames.reserve(filenames_tensor->NumElements());
  for (int i = 0; i < filenames_tensor->NumElements(); ++i) {
    VLOG(2) << "Reading file: " << filenames_tensor->flat<tstring>()(i);
    filenames.push_back(filenames_tensor->flat<tstring>()(i));
  }

  tstring compression_type;
  OP_REQUIRES_OK(ctx, ParseScalarArgument<tstring>(ctx, kCompressionType,
                                                   &compression_type));

  int64 buffer_size = -1;
  OP_REQUIRES_OK(ctx,
                 ParseScalarArgument<int64>(ctx, kBufferSize, &buffer_size));
  OP_REQUIRES(ctx, buffer_size >= 0,
              errors::InvalidArgument(
                  "`buffer_size` must be >= 0 (0 == no buffering)"));

  *output =
      new Dataset(ctx, std::move(filenames), compression_type, buffer_size);
}

namespace {
REGISTER_KERNEL_BUILDER(Name("TFRecordDataset").Device(DEVICE_CPU),
                        TFRecordDatasetOp);
}  // namespace
}  // namespace data
}  // namespace tensorflow
<commit_msg>Override buffer size when running on cloud tpu. A small buffer size adds a performance slowdown. Here we override the buffer size to a minimum recommended buffer size.<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/kernels/data/tf_record_dataset_op.h"

#include "tensorflow/core/common_runtime/metrics.h"
#include "tensorflow/core/framework/partial_tensor_shape.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/kernels/data/name_utils.h"
#include "tensorflow/core/lib/io/buffered_inputstream.h"
#include "tensorflow/core/lib/io/inputbuffer.h"
#include "tensorflow/core/lib/io/random_inputstream.h"
#include "tensorflow/core/lib/io/record_reader.h"
#include "tensorflow/core/lib/io/zlib_compression_options.h"
#include "tensorflow/core/lib/io/zlib_inputstream.h"

namespace tensorflow {
namespace data {

// See documentation in ../../ops/dataset_ops.cc for a high-level
// description of the following ops.

/* static */ constexpr const char* const TFRecordDatasetOp::kDatasetType;
/* static */ constexpr const char* const TFRecordDatasetOp::kFileNames;
/* static */ constexpr const char* const TFRecordDatasetOp::kCompressionType;
/* static */ constexpr const char* const TFRecordDatasetOp::kBufferSize;

constexpr char kCurrentFileIndex[] = "current_file_index";
constexpr char kOffset[] = "offset";
constexpr char kGcsFsPrefix[] = "gs://";
constexpr int64 kCloudTpuBlockSize = 127LL << 20;  // 127MB.

bool is_cloud_tpu_gcs_fs() {
#if defined(PLATFORM_CLOUD_TPU) && defined(TPU_GCS_FS)
  return true;
#endif
  return false;
}

class TFRecordDatasetOp::Dataset : public DatasetBase {
 public:
  explicit Dataset(OpKernelContext* ctx, std::vector<string> filenames,
                   const string& compression_type, int64 buffer_size)
      : DatasetBase(DatasetContext(ctx)),
        filenames_(std::move(filenames)),
        compression_type_(compression_type),
        options_(io::RecordReaderOptions::CreateRecordReaderOptions(
            compression_type)) {
    if (buffer_size > 0) {
      options_.buffer_size = buffer_size;
    }
  }

  std::unique_ptr<IteratorBase> MakeIteratorInternal(
      const string& prefix) const override {
    return absl::make_unique<Iterator>(Iterator::Params{
        this, name_utils::IteratorPrefix(kDatasetType, prefix)});
  }

  const DataTypeVector& output_dtypes() const override {
    static DataTypeVector* dtypes = new DataTypeVector({DT_STRING});
    return *dtypes;
  }

  const std::vector<PartialTensorShape>& output_shapes() const override {
    static std::vector<PartialTensorShape>* shapes =
        new std::vector<PartialTensorShape>({{}});
    return *shapes;
  }

  string DebugString() const override {
    return name_utils::DatasetDebugString(kDatasetType);
  }

  Status CheckExternalState() const override { return Status::OK(); }

 protected:
  Status AsGraphDefInternal(SerializationContext* ctx,
                            DatasetGraphDefBuilder* b,
                            Node** output) const override {
    Node* filenames = nullptr;
    TF_RETURN_IF_ERROR(b->AddVector(filenames_, &filenames));
    Node* compression_type = nullptr;
    TF_RETURN_IF_ERROR(b->AddScalar(compression_type_, &compression_type));
    Node* buffer_size = nullptr;
    TF_RETURN_IF_ERROR(b->AddScalar(options_.buffer_size, &buffer_size));
    TF_RETURN_IF_ERROR(b->AddDataset(
        this, {filenames, compression_type, buffer_size}, output));
    return Status::OK();
  }

 private:
  class Iterator : public DatasetIterator<Dataset> {
   public:
    explicit Iterator(const Params& params)
        : DatasetIterator<Dataset>(params) {}

    Status GetNextInternal(IteratorContext* ctx,
                           std::vector<Tensor>* out_tensors,
                           bool* end_of_sequence) override {
      out_tensors->reserve(1);
      mutex_lock l(mu_);
      do {
        // We are currently processing a file, so try to read the next record.
        if (reader_) {
          out_tensors->emplace_back(ctx->allocator({}), DT_STRING,
                                    TensorShape({}));
          Status s =
              reader_->ReadRecord(&out_tensors->back().scalar<tstring>()());
          if (s.ok()) {
            metrics::RecordTFDataBytesRead(
                kDatasetType, out_tensors->back().scalar<tstring>()().size());
            *end_of_sequence = false;
            return Status::OK();
          }
          out_tensors->pop_back();
          if (!errors::IsOutOfRange(s)) {
            // In case of other errors e.g., DataLoss, we still move forward
            // the file index so that it works with ignore_errors.
            // Otherwise the same file will repeat.
            ResetStreamsLocked();
            ++current_file_index_;
            return s;
          }

          // We have reached the end of the current file, so maybe move on to
          // next file.
          ResetStreamsLocked();
          ++current_file_index_;
        }

        // Iteration ends when there are no more files to process.
        if (current_file_index_ == dataset()->filenames_.size()) {
          *end_of_sequence = true;
          return Status::OK();
        }

        TF_RETURN_IF_ERROR(SetupStreamsLocked(ctx->env()));
      } while (true);
    }

   protected:
    std::shared_ptr<model::Node> CreateNode(
        IteratorContext* ctx, model::Node::Args args) const override {
      return model::MakeSourceNode(std::move(args));
    }

    Status SaveInternal(IteratorStateWriter* writer) override {
      mutex_lock l(mu_);
      TF_RETURN_IF_ERROR(writer->WriteScalar(full_name(kCurrentFileIndex),
                                             current_file_index_));

      if (reader_) {
        TF_RETURN_IF_ERROR(
            writer->WriteScalar(full_name(kOffset), reader_->TellOffset()));
      }
      return Status::OK();
    }

    Status RestoreInternal(IteratorContext* ctx,
                           IteratorStateReader* reader) override {
      mutex_lock l(mu_);
      ResetStreamsLocked();
      int64 current_file_index;
      TF_RETURN_IF_ERROR(reader->ReadScalar(full_name(kCurrentFileIndex),
                                            &current_file_index));
      current_file_index_ = size_t(current_file_index);
      if (reader->Contains(full_name(kOffset))) {
        int64 offset;
        TF_RETURN_IF_ERROR(reader->ReadScalar(full_name(kOffset), &offset));
        TF_RETURN_IF_ERROR(SetupStreamsLocked(ctx->env()));
        TF_RETURN_IF_ERROR(reader_->SeekOffset(offset));
      }
      return Status::OK();
    }

   private:
    // Sets up reader streams to read from the file at `current_file_index_`.
    Status SetupStreamsLocked(Env* env) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
      if (current_file_index_ >= dataset()->filenames_.size()) {
        return errors::InvalidArgument(
            "current_file_index_:", current_file_index_,
            " >= filenames_.size():", dataset()->filenames_.size());
      }

      // Actually move on to next file.
      const string& next_filename = dataset()->filenames_[current_file_index_];
      TF_RETURN_IF_ERROR(env->NewRandomAccessFile(next_filename, &file_));
      reader_ = absl::make_unique<io::SequentialRecordReader>(
          file_.get(), dataset()->options_);
      return Status::OK();
    }

    // Resets all reader streams.
    void ResetStreamsLocked() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
      reader_.reset();
      file_.reset();
    }

    mutex mu_;
    size_t current_file_index_ GUARDED_BY(mu_) = 0;

    // `reader_` will borrow the object that `file_` points to, so
    // we must destroy `reader_` before `file_`.
    std::unique_ptr<RandomAccessFile> file_ GUARDED_BY(mu_);
    std::unique_ptr<io::SequentialRecordReader> reader_ GUARDED_BY(mu_);
  };

  const std::vector<string> filenames_;
  const tstring compression_type_;
  io::RecordReaderOptions options_;
};

TFRecordDatasetOp::TFRecordDatasetOp(OpKernelConstruction* ctx)
    : DatasetOpKernel(ctx) {}

void TFRecordDatasetOp::MakeDataset(OpKernelContext* ctx,
                                    DatasetBase** output) {
  const Tensor* filenames_tensor;
  OP_REQUIRES_OK(ctx, ctx->input(kFileNames, &filenames_tensor));
  OP_REQUIRES(
      ctx, filenames_tensor->dims() <= 1,
      errors::InvalidArgument("`filenames` must be a scalar or a vector."));

  bool is_gcs_fs = true;
  std::vector<string> filenames;
  filenames.reserve(filenames_tensor->NumElements());
  for (int i = 0; i < filenames_tensor->NumElements(); ++i) {
    VLOG(2) << "Reading file: " << filenames_tensor->flat<tstring>()(i);
    filenames.push_back(filenames_tensor->flat<tstring>()(i));
    is_gcs_fs &= absl::StartsWith(filenames[i], kGcsFsPrefix);
  }

  tstring compression_type;
  OP_REQUIRES_OK(ctx, ParseScalarArgument<tstring>(ctx, kCompressionType,
                                                   &compression_type));

  int64 buffer_size = -1;
  OP_REQUIRES_OK(ctx,
                 ParseScalarArgument<int64>(ctx, kBufferSize, &buffer_size));
  OP_REQUIRES(ctx, buffer_size >= 0,
              errors::InvalidArgument(
                  "`buffer_size` must be >= 0 (0 == no buffering)"));

  if (is_gcs_fs && is_cloud_tpu_gcs_fs() && buffer_size < kCloudTpuBlockSize) {
    LOG(WARNING) << "User buffer size is too small for reading Cloud TPU "
                 << "TFRecords stored in GCS. Overriding " << buffer_size
                 << " to the minimum recommended buffer_size = "
                 << kCloudTpuBlockSize;
    buffer_size = kCloudTpuBlockSize;
  }

  *output =
      new Dataset(ctx, std::move(filenames), compression_type, buffer_size);
}

namespace {
REGISTER_KERNEL_BUILDER(Name("TFRecordDataset").Device(DEVICE_CPU),
                        TFRecordDatasetOp);
}  // namespace
}  // namespace data
}  // namespace tensorflow
<|endoftext|>


<commit_before>// Copyright (c) 2017-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_HPP
#define TAO_PEGTL_CONTRIB_PARSE_TREE_HPP

#include <cassert>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <utility>
#include <vector>

#include "remove_first_state.hpp"
#include "shuffle_states.hpp"

#include "../apply_mode.hpp"
#include "../config.hpp"
#include "../demangle.hpp"
#include "../memory_input.hpp"
#include "../normal.hpp"
#include "../nothing.hpp"
#include "../parse.hpp"
#include "../rewind_mode.hpp"

#include "../internal/enable_control.hpp"
#include "../internal/has_unwind.hpp"
#include "../internal/iterator.hpp"

namespace TAO_PEGTL_NAMESPACE::parse_tree
{
   template< typename T >
   struct basic_node
   {
      using node_t = T;
      using children_t = std::vector< std::unique_ptr< node_t > >;
      children_t children;

      std::string_view type;
      std::string source;

      TAO_PEGTL_NAMESPACE::internal::iterator m_begin;
      TAO_PEGTL_NAMESPACE::internal::iterator m_end;

      // each node will be default constructed
      basic_node() = default;

      // no copy/move is necessary
      // (nodes are always owned/handled by a std::unique_ptr)
      basic_node( const basic_node& ) = delete;
      basic_node( basic_node&& ) = delete;

      ~basic_node() = default;

      // no assignment either
      basic_node& operator=( const basic_node& ) = delete;
      basic_node& operator=( basic_node&& ) = delete;

      [[nodiscard]] bool is_root() const noexcept
      {
         return type.empty();
      }

      template< typename U >
      [[nodiscard]] bool is_type() const noexcept
      {
         return type == demangle< U >();
      }

      template< typename U >
      void set_type() noexcept
      {
         type = demangle< U >();
      }

      [[nodiscard]] position begin() const
      {
         return position( m_begin, source );
      }

      [[nodiscard]] position end() const
      {
         return position( m_end, source );
      }

      [[nodiscard]] bool has_content() const noexcept
      {
         return m_end.data != nullptr;
      }

      [[nodiscard]] std::string_view string_view() const noexcept
      {
         assert( has_content() );
         return std::string_view( m_begin.data, m_end.data - m_begin.data );
      }

      [[nodiscard]] std::string string() const
      {
         assert( has_content() );
         return std::string( m_begin.data, m_end.data );
      }

      template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
      [[nodiscard]] memory_input< P, Eol > as_memory_input() const
      {
         assert( has_content() );
         return { m_begin.data, m_end.data, source, m_begin.byte, m_begin.line, m_begin.column };
      }

      template< typename... States >
      void remove_content( States&&... /*unused*/ ) noexcept
      {
         m_end = TAO_PEGTL_NAMESPACE::internal::iterator();
      }

      // all non-root nodes are initialized by calling this method
      template< typename Rule, typename ParseInput, typename... States >
      void start( const ParseInput& in, States&&... /*unused*/ )
      {
         set_type< Rule >();
         source = in.source();
         m_begin = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
      }

      // if parsing of the rule succeeded, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void success( const ParseInput& in, States&&... /*unused*/ ) noexcept
      {
         m_end = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
      }

      // if parsing of the rule failed, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
      {}

      // if parsing of the rule failed with an exception, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
      {}

      // if parsing succeeded and the (optional) transform call
      // did not discard the node, it is appended to its parent.
      // note that "child" is the node whose Rule just succeeded
      // and "*this" is the parent where the node should be appended.
      template< typename... States >
      void emplace_back( std::unique_ptr< node_t >&& child, States&&... /*unused*/ )
      {
         assert( child );
         children.emplace_back( std::move( child ) );
      }
   };

   struct node
      : basic_node< node >
   {};

   namespace internal
   {
      template< typename Node >
      struct state
      {
         std::vector< std::unique_ptr< Node > > stack;

         state()
         {
            emplace_back();
         }

         void emplace_back()
         {
            stack.emplace_back( std::make_unique< Node >() );
         }

         [[nodiscard]] std::unique_ptr< Node >& back() noexcept
         {
            assert( !stack.empty() );
            return stack.back();
         }

         void pop_back() noexcept
         {
            assert( !stack.empty() );
            return stack.pop_back();
         }
      };

      template< typename Selector, typename... Parameters >
      void transform( Parameters&&... /*unused*/ ) noexcept
      {}

      template< typename Selector, typename ParseInput, typename Node, typename... States >
      auto transform( const ParseInput& in, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( in, n, st... ) ) )
         -> decltype( (void)Selector::transform( in, n, st... ) )
      {
         Selector::transform( in, n, st... );
      }

      template< typename Selector, typename ParseInput, typename Node, typename... States >
      auto transform( const ParseInput& /*unused*/, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( n, st... ) ) )
         -> decltype( (void)Selector::transform( n, st... ) )
      {
         Selector::transform( n, st... );
      }

      template< typename Rule, template< typename... > class Selector >
      inline constexpr bool is_selected_node = ( TAO_PEGTL_NAMESPACE::internal::enable_control< Rule > && Selector< Rule >::value );

      template< unsigned Level, typename Subs, template< typename... > class Selector >
      inline constexpr bool is_leaf{};

      template< typename... Rules, template< typename... > class Selector >
      inline constexpr bool is_leaf< 0, type_list< Rules... >, Selector > = ( sizeof...( Rules ) == 0 );

      template< unsigned Level, typename Rule, template< typename... > class Selector >
      inline constexpr bool is_unselected_branch = ( !is_selected_node< Rule, Selector > && is_leaf< Level, typename Rule::subs_t, Selector > );

      template< unsigned Level, typename... Rules, template< typename... > class Selector >
      inline constexpr bool is_leaf< Level, type_list< Rules... >, Selector > = ( is_unselected_branch< Level - 1, Rules, Selector > && ... );

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      struct make_control
      {
         template< typename Rule, bool, bool >
         struct state_handler;

         template< typename Rule >
         using type = rotate_states_right< state_handler< Rule, is_selected_node< Rule, Selector >, is_leaf< 8, typename Rule::subs_t, Selector > > >;
      };

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule >
      struct make_control< Node, Selector, Control >::state_handler< Rule, false, true >
         : remove_first_state< Control< Rule > >
      {};

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule >
      struct make_control< Node, Selector, Control >::state_handler< Rule, false, false >
         : remove_first_state< Control< Rule > >
      {
         static constexpr bool enable = true;

         template< typename ParseInput, typename... States >
         static void start( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.emplace_back();
         }

         template< typename ParseInput, typename... States >
         static void success( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            auto n = std::move( state.back() );
            state.pop_back();
            for( auto& c : n->children ) {
               state.back()->children.emplace_back( std::move( c ) );
            }
         }

         template< typename ParseInput, typename... States >
         static void failure( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.pop_back();
         }

         template< typename ParseInput, typename... States >
         static void unwind( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.pop_back();
         }
      };

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule, bool B >
      struct make_control< Node, Selector, Control >::state_handler< Rule, true, B >
         : remove_first_state< Control< Rule > >
      {
         template< typename ParseInput, typename... States >
         static void start( const ParseInput& in, state< Node >& state, States&&... st )
         {
            Control< Rule >::start( in, st... );
            state.emplace_back();
            state.back()->template start< Rule >( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void success( const ParseInput& in, state< Node >& state, States&&... st )
         {
            auto n = std::move( state.back() );
            state.pop_back();
            n->template success< Rule >( in, st... );
            transform< Selector< Rule > >( in, n, st... );
            if( n ) {
               state.back()->emplace_back( std::move( n ), st... );
            }
            Control< Rule >::success( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void failure( const ParseInput& in, state< Node >& state, States&&... st )
         {
            state.back()->template failure< Rule >( in, st... );
            state.pop_back();
            Control< Rule >::failure( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void unwind( const ParseInput& in, state< Node >& state, States&&... st )
         {
            state.back()->template unwind< Rule >( in, st... );
            state.pop_back();
            if constexpr( TAO_PEGTL_NAMESPACE::internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) {
               Control< Rule >::unwind( in, st... );
            }
         }
      };

      template< typename >
      using store_all = std::true_type;

      template< typename >
      struct selector;

      template< typename T >
      struct selector< std::tuple< T > >
      {
         using type = typename T::type;
      };

      template< typename... Ts >
      struct selector< std::tuple< Ts... > >
      {
         static_assert( sizeof...( Ts ) == 0, "multiple matches found" );
         using type = std::false_type;
      };

      template< typename T >
      using selector_t = typename selector< T >::type;

      template< typename Rule, typename Collection >
      using select_tuple = std::conditional_t< Collection::template contains< Rule >, std::tuple< Collection >, std::tuple<> >;

   }  // namespace internal

   template< typename Rule, typename... Collections >
   using selector = internal::selector_t< decltype( std::tuple_cat( std::declval< internal::select_tuple< Rule, Collections > >()... ) ) >;

   template< typename Base >
   struct apply
      : std::true_type
   {
      template< typename... Rules >
      struct on
      {
         using type = Base;

         template< typename Rule >
         static constexpr bool contains = ( std::is_same_v< Rule, Rules > || ... );
      };
   };

   struct store_content
      : apply< store_content >
   {};

   // some nodes don't need to store their content
   struct remove_content
      : apply< remove_content >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->Node::remove_content( st... ) ) )
      {
         n->remove_content( st... );
      }
   };

   // if a node has only one child, replace the node with its child, otherwise remove content
   struct fold_one
      : apply< fold_one >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.size(), n->Node::remove_content( st... ) ) )
      {
         if( n->children.size() == 1 ) {
            n = std::move( n->children.front() );
         }
         else {
            n->remove_content( st... );
         }
      }
   };

   // if a node has no children, discard the node, otherwise remove content
   struct discard_empty
      : apply< discard_empty >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( (void)n->children.empty(), n->Node::remove_content( st... ) ) )
      {
         if( n->children.empty() ) {
            n.reset();
         }
         else {
            n->remove_content( st... );
         }
      }
   };

   template< typename Rule,
             typename Node,
             template< typename... > class Selector = internal::store_all,
             template< typename... > class Action = nothing,
             template< typename... > class Control = normal,
             typename ParseInput,
             typename... States >
   [[nodiscard]] std::unique_ptr< Node > parse( ParseInput&& in, States&&... st )
   {
      internal::state< Node > state;
      if( !TAO_PEGTL_NAMESPACE::parse< Rule, Action, internal::make_control< Node, Selector, Control >::template type >( in, st..., state ) ) {
         return nullptr;
      }
      assert( state.stack.size() == 1 );
      return std::move( state.back() );
   }

   template< typename Rule,
             template< typename... > class Selector = internal::store_all,
             template< typename... > class Action = nothing,
             template< typename... > class Control = normal,
             typename ParseInput,
             typename... States >
   [[nodiscard]] std::unique_ptr< node > parse( ParseInput&& in, States&&... st )
   {
      return parse< Rule, node, Selector, Action, Control >( in, st... );
   }

}  // namespace TAO_PEGTL_NAMESPACE::parse_tree

#endif
<commit_msg>parse_tree::basic_node now uses template Source, defaults to string_view<commit_after>// Copyright (c) 2017-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_HPP
#define TAO_PEGTL_CONTRIB_PARSE_TREE_HPP

#include <cassert>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <utility>
#include <vector>

#include "remove_first_state.hpp"
#include "shuffle_states.hpp"

#include "../apply_mode.hpp"
#include "../config.hpp"
#include "../demangle.hpp"
#include "../memory_input.hpp"
#include "../normal.hpp"
#include "../nothing.hpp"
#include "../parse.hpp"
#include "../rewind_mode.hpp"

#include "../internal/enable_control.hpp"
#include "../internal/has_unwind.hpp"
#include "../internal/iterator.hpp"

namespace TAO_PEGTL_NAMESPACE::parse_tree
{
   template< typename T, typename Source = std::string_view >
   struct basic_node
   {
      using node_t = T;
      using children_t = std::vector< std::unique_ptr< node_t > >;
      children_t children;

      std::string_view type;
      Source source;

      TAO_PEGTL_NAMESPACE::internal::iterator m_begin;
      TAO_PEGTL_NAMESPACE::internal::iterator m_end;

      // each node will be default constructed
      basic_node() = default;

      // no copy/move is necessary
      // (nodes are always owned/handled by a std::unique_ptr)
      basic_node( const basic_node& ) = delete;
      basic_node( basic_node&& ) = delete;

      ~basic_node() = default;

      // no assignment either
      basic_node& operator=( const basic_node& ) = delete;
      basic_node& operator=( basic_node&& ) = delete;

      [[nodiscard]] bool is_root() const noexcept
      {
         return type.empty();
      }

      template< typename U >
      [[nodiscard]] bool is_type() const noexcept
      {
         return type == demangle< U >();
      }

      template< typename U >
      void set_type() noexcept
      {
         type = demangle< U >();
      }

      [[nodiscard]] position begin() const
      {
         return position( m_begin, source );
      }

      [[nodiscard]] position end() const
      {
         return position( m_end, source );
      }

      [[nodiscard]] bool has_content() const noexcept
      {
         return m_end.data != nullptr;
      }

      [[nodiscard]] std::string_view string_view() const noexcept
      {
         assert( has_content() );
         return std::string_view( m_begin.data, m_end.data - m_begin.data );
      }

      [[nodiscard]] std::string string() const
      {
         assert( has_content() );
         return std::string( m_begin.data, m_end.data );
      }

      template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
      [[nodiscard]] memory_input< P, Eol > as_memory_input() const
      {
         assert( has_content() );
         return { m_begin.data, m_end.data, source, m_begin.byte, m_begin.line, m_begin.column };
      }

      template< typename... States >
      void remove_content( States&&... /*unused*/ ) noexcept
      {
         m_end = TAO_PEGTL_NAMESPACE::internal::iterator();
      }

      // all non-root nodes are initialized by calling this method
      template< typename Rule, typename ParseInput, typename... States >
      void start( const ParseInput& in, States&&... /*unused*/ )
      {
         set_type< Rule >();
         source = in.source();
         m_begin = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
      }

      // if parsing of the rule succeeded, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void success( const ParseInput& in, States&&... /*unused*/ ) noexcept
      {
         m_end = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
      }

      // if parsing of the rule failed, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
      {}

      // if parsing of the rule failed with an exception, this method is called
      template< typename Rule, typename ParseInput, typename... States >
      void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
      {}

      // if parsing succeeded and the (optional) transform call
      // did not discard the node, it is appended to its parent.
      // note that "child" is the node whose Rule just succeeded
      // and "*this" is the parent where the node should be appended.
      template< typename... States >
      void emplace_back( std::unique_ptr< node_t >&& child, States&&... /*unused*/ )
      {
         assert( child );
         children.emplace_back( std::move( child ) );
      }
   };

   struct node
      : basic_node< node >
   {};

   namespace internal
   {
      template< typename Node >
      struct state
      {
         std::vector< std::unique_ptr< Node > > stack;

         state()
         {
            emplace_back();
         }

         void emplace_back()
         {
            stack.emplace_back( std::make_unique< Node >() );
         }

         [[nodiscard]] std::unique_ptr< Node >& back() noexcept
         {
            assert( !stack.empty() );
            return stack.back();
         }

         void pop_back() noexcept
         {
            assert( !stack.empty() );
            return stack.pop_back();
         }
      };

      template< typename Selector, typename... Parameters >
      void transform( Parameters&&... /*unused*/ ) noexcept
      {}

      template< typename Selector, typename ParseInput, typename Node, typename... States >
      auto transform( const ParseInput& in, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( in, n, st... ) ) )
         -> decltype( (void)Selector::transform( in, n, st... ) )
      {
         Selector::transform( in, n, st... );
      }

      template< typename Selector, typename ParseInput, typename Node, typename... States >
      auto transform( const ParseInput& /*unused*/, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( n, st... ) ) )
         -> decltype( (void)Selector::transform( n, st... ) )
      {
         Selector::transform( n, st... );
      }

      template< typename Rule, template< typename... > class Selector >
      inline constexpr bool is_selected_node = ( TAO_PEGTL_NAMESPACE::internal::enable_control< Rule > && Selector< Rule >::value );

      template< unsigned Level, typename Subs, template< typename... > class Selector >
      inline constexpr bool is_leaf{};

      template< typename... Rules, template< typename... > class Selector >
      inline constexpr bool is_leaf< 0, type_list< Rules... >, Selector > = ( sizeof...( Rules ) == 0 );

      template< unsigned Level, typename Rule, template< typename... > class Selector >
      inline constexpr bool is_unselected_branch = ( !is_selected_node< Rule, Selector > && is_leaf< Level, typename Rule::subs_t, Selector > );

      template< unsigned Level, typename... Rules, template< typename... > class Selector >
      inline constexpr bool is_leaf< Level, type_list< Rules... >, Selector > = ( is_unselected_branch< Level - 1, Rules, Selector > && ... );

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      struct make_control
      {
         template< typename Rule, bool, bool >
         struct state_handler;

         template< typename Rule >
         using type = rotate_states_right< state_handler< Rule, is_selected_node< Rule, Selector >, is_leaf< 8, typename Rule::subs_t, Selector > > >;
      };

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule >
      struct make_control< Node, Selector, Control >::state_handler< Rule, false, true >
         : remove_first_state< Control< Rule > >
      {};

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule >
      struct make_control< Node, Selector, Control >::state_handler< Rule, false, false >
         : remove_first_state< Control< Rule > >
      {
         static constexpr bool enable = true;

         template< typename ParseInput, typename... States >
         static void start( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.emplace_back();
         }

         template< typename ParseInput, typename... States >
         static void success( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            auto n = std::move( state.back() );
            state.pop_back();
            for( auto& c : n->children ) {
               state.back()->children.emplace_back( std::move( c ) );
            }
         }

         template< typename ParseInput, typename... States >
         static void failure( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.pop_back();
         }

         template< typename ParseInput, typename... States >
         static void unwind( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
         {
            state.pop_back();
         }
      };

      template< typename Node, template< typename... > class Selector, template< typename... > class Control >
      template< typename Rule, bool B >
      struct make_control< Node, Selector, Control >::state_handler< Rule, true, B >
         : remove_first_state< Control< Rule > >
      {
         template< typename ParseInput, typename... States >
         static void start( const ParseInput& in, state< Node >& state, States&&... st )
         {
            Control< Rule >::start( in, st... );
            state.emplace_back();
            state.back()->template start< Rule >( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void success( const ParseInput& in, state< Node >& state, States&&... st )
         {
            auto n = std::move( state.back() );
            state.pop_back();
            n->template success< Rule >( in, st... );
            transform< Selector< Rule > >( in, n, st... );
            if( n ) {
               state.back()->emplace_back( std::move( n ), st... );
            }
            Control< Rule >::success( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void failure( const ParseInput& in, state< Node >& state, States&&... st )
         {
            state.back()->template failure< Rule >( in, st... );
            state.pop_back();
            Control< Rule >::failure( in, st... );
         }

         template< typename ParseInput, typename... States >
         static void unwind( const ParseInput& in, state< Node >& state, States&&... st )
         {
            state.back()->template unwind< Rule >( in, st... );
            state.pop_back();
            if constexpr( TAO_PEGTL_NAMESPACE::internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) {
               Control< Rule >::unwind( in, st... );
            }
         }
      };

      template< typename >
      using store_all = std::true_type;

      template< typename >
      struct selector;

      template< typename T >
      struct selector< std::tuple< T > >
      {
         using type = typename T::type;
      };

      template< typename... Ts >
      struct selector< std::tuple< Ts... > >
      {
         static_assert( sizeof...( Ts ) == 0, "multiple matches found" );
         using type = std::false_type;
      };

      template< typename T >
      using selector_t = typename selector< T >::type;

      template< typename Rule, typename Collection >
      using select_tuple = std::conditional_t< Collection::template contains< Rule >, std::tuple< Collection >, std::tuple<> >;

   }  // namespace internal

   template< typename Rule, typename... Collections >
   using selector = internal::selector_t< decltype( std::tuple_cat( std::declval< internal::select_tuple< Rule, Collections > >()... ) ) >;

   template< typename Base >
   struct apply
      : std::true_type
   {
      template< typename... Rules >
      struct on
      {
         using type = Base;

         template< typename Rule >
         static constexpr bool contains = ( std::is_same_v< Rule, Rules > || ... );
      };
   };

   struct store_content
      : apply< store_content >
   {};

   // some nodes don't need to store their content
   struct remove_content
      : apply< remove_content >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->Node::remove_content( st... ) ) )
      {
         n->remove_content( st... );
      }
   };

   // if a node has only one child, replace the node with its child, otherwise remove content
   struct fold_one
      : apply< fold_one >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.size(), n->Node::remove_content( st... ) ) )
      {
         if( n->children.size() == 1 ) {
            n = std::move( n->children.front() );
         }
         else {
            n->remove_content( st... );
         }
      }
   };

   // if a node has no children, discard the node, otherwise remove content
   struct discard_empty
      : apply< discard_empty >
   {
      template< typename Node, typename... States >
      static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( (void)n->children.empty(), n->Node::remove_content( st... ) ) )
      {
         if( n->children.empty() ) {
            n.reset();
         }
         else {
            n->remove_content( st... );
         }
      }
   };

   template< typename Rule,
             typename Node,
             template< typename... > class Selector = internal::store_all,
             template< typename... > class Action = nothing,
             template< typename... > class Control = normal,
             typename ParseInput,
             typename... States >
   [[nodiscard]] std::unique_ptr< Node > parse( ParseInput&& in, States&&... st )
   {
      internal::state< Node > state;
      if( !TAO_PEGTL_NAMESPACE::parse< Rule, Action, internal::make_control< Node, Selector, Control >::template type >( in, st..., state ) ) {
         return nullptr;
      }
      assert( state.stack.size() == 1 );
      return std::move( state.back() );
   }

   template< typename Rule,
             template< typename... > class Selector = internal::store_all,
             template< typename... > class Action = nothing,
             template< typename... > class Control = normal,
             typename ParseInput,
             typename... States >
   [[nodiscard]] std::unique_ptr< node > parse( ParseInput&& in, States&&... st )
   {
      return parse< Rule, node, Selector, Action, Control >( in, st... );
   }

}  // namespace TAO_PEGTL_NAMESPACE::parse_tree

#endif
<|endoftext|>