<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TORRENT_HANDLE_HPP_INCLUDED
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED

#include <vector>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/date_time/posix_time/posix_time.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/peer_id.hpp"
#include "libtorrent/peer_info.hpp"
#include "libtorrent/piece_picker.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{
	namespace aux
	{
		struct session_impl;
		struct checker_impl;
	}

	struct TORRENT_EXPORT duplicate_torrent: std::exception
	{
		virtual const char* what() const throw()
		{ return "torrent already exists in session"; }
	};

	struct TORRENT_EXPORT invalid_handle: std::exception
	{
		virtual const char* what() const throw()
		{ return "invalid torrent handle used"; }
	};

	struct TORRENT_EXPORT torrent_status
	{
		torrent_status()
			: state(queued_for_checking)
			, paused(false)
			, progress(0.f)
			, total_download(0)
			, total_upload(0)
			, total_payload_download(0)
			, total_payload_upload(0)
			, total_failed_bytes(0)
			, total_redundant_bytes(0)
			, download_rate(0)
			, upload_rate(0)
			, download_payload_rate(0)
			, upload_payload_rate(0)
			, num_peers(0)
			, num_complete(-1)
			, num_incomplete(-1)
			, pieces(0)
			, num_pieces(0)
			, total_done(0)
			, total_wanted_done(0)
			, total_wanted(0)
			, num_seeds(0)
			, distributed_copies(0.f)
			, block_size(0)
		{}

		enum state_t
		{
			queued_for_checking,
			checking_files,
			connecting_to_tracker,
			downloading_metadata,
			downloading,
			finished,
			seeding,
			allocating
		};

		state_t state;
		bool paused;
		float progress;
		boost::posix_time::time_duration next_announce;
		boost::posix_time::time_duration announce_interval;

		std::string current_tracker;

		// transferred this session!
		// total, payload plus protocol
		size_type total_download;
		size_type total_upload;

		// payload only
		size_type total_payload_download;
		size_type total_payload_upload;

		// the amount of payload bytes that
		// has failed their hash test
		size_type total_failed_bytes;

		// the number of payload bytes that
		// has been received redundantly.
		size_type total_redundant_bytes;

		// current transfer rate
		// payload plus protocol
		float download_rate;
		float upload_rate;

		// the rate of payload that is
		// sent and received
		float download_payload_rate;
		float upload_payload_rate;

		// the number of peers this torrent
		// is connected to.
		int num_peers;

		// if the tracker sends scrape info in its
		// announce reply, these fields will be
		// set to the total number of peers that
		// have the whole file and the total number
		// of peers that are still downloading
		int num_complete;
		int num_incomplete;

		const std::vector<bool>* pieces;

		// this is the number of pieces the client has
		// downloaded. it is equal to:
		// std::accumulate(pieces->begin(), pieces->end());
		int num_pieces;

		// the number of bytes of the file we have
		// including pieces that may have been filtered
		// after we downloaded them
		size_type total_done;

		// the number of bytes we have of those that we
		// want. i.e. not counting bytes from pieces that
		// are filtered as not wanted.
		size_type total_wanted_done;

		// the total number of bytes we want to download
		// this may be smaller than the total torrent size
		// in case any pieces are filtered as not wanted
		size_type total_wanted;

		// the number of peers this torrent is connected to
		// that are seeding.
		int num_seeds;

		// the number of distributed copies of the file.
		// note that one copy may be spread out among many peers.
		//
		// the whole number part tells how many copies
		//   there are of the rarest piece(s)
		//
		// the fractional part tells the fraction of pieces that
		//   have more copies than the rarest piece(s).
		float distributed_copies;

		// the block size that is used in this torrent. i.e.
		// the number of bytes each piece request asks for
		// and each bit in the download queue bitfield represents
		int block_size;
	};

	struct TORRENT_EXPORT partial_piece_info
	{
		enum { max_blocks_per_piece = piece_picker::max_blocks_per_piece };
		int piece_index;
		int blocks_in_piece;
		std::bitset<max_blocks_per_piece> requested_blocks;
		std::bitset<max_blocks_per_piece> finished_blocks;
		tcp::endpoint peer[max_blocks_per_piece];
		int num_downloads[max_blocks_per_piece];
	};

	struct TORRENT_EXPORT torrent_handle
	{
		friend class invariant_access;
		friend class aux::session_impl;
		friend class torrent;

		torrent_handle(): m_ses(0), m_chk(0) {}

		void get_peer_info(std::vector<peer_info>& v) const;
		bool send_chat_message(tcp::endpoint ip, std::string message) const;
		torrent_status status() const;
		void get_download_queue(std::vector<partial_piece_info>& queue) const;

		// fills the specified vector with the download progress [0, 1]
		// of each file in the torrent. The files are ordered as in
		// the torrent_info.
		void file_progress(std::vector<float>& progress);

		std::vector<announce_entry> const& trackers() const;
		void replace_trackers(std::vector<announce_entry> const&) const;

		void add_url_seed(std::string const& url);

		bool has_metadata() const;
		const torrent_info& get_torrent_info() const;
		bool is_valid() const;

		bool is_seed() const;
		bool is_paused() const;
		void pause() const;
		void resume() const;

		// marks the piece with the given index as filtered
		// it will not be downloaded
		void filter_piece(int index, bool filter) const;
		void filter_pieces(std::vector<bool> const& pieces) const;
		bool is_piece_filtered(int index) const;
		std::vector<bool> filtered_pieces() const;

		// marks the file with the given index as filtered
		// it will not be downloaded
		void filter_files(std::vector<bool> const& files) const;

		// set the interface to bind outgoing connections
		// to.
		void use_interface(const char* net_interface) const;

		entry write_resume_data() const;

		// kind of similar to get_torrent_info() but this
		// is lower level, returning the exact info-part of
		// the .torrent file. When hashed, this buffer
		// will produce the info hash. The reference is valid
		// only as long as the torrent is running.
		std::vector<char> const& metadata() const;

		// forces this torrent to reannounce
		// (make a rerequest from the tracker)
		void force_reannounce() const;

		// forces a reannounce in the specified amount of time.
		// This overrides the default announce interval, and no
		// announce will take place until the given time has
		// timed out.
		void force_reannounce(boost::posix_time::time_duration) const;

		// TODO: add a feature where the user can tell the torrent
		// to finish all pieces currently in the pipeline, and then
		// abort the torrent.

		void set_upload_limit(int limit) const;
		void set_download_limit(int limit) const;
		void set_sequenced_download_threshold(int threshold) const;

		void set_peer_upload_limit(tcp::endpoint ip, int limit) const;
		void set_peer_download_limit(tcp::endpoint ip, int limit) const;

		// manually connect a peer
		void connect_peer(tcp::endpoint const& adr) const;

		// valid ratios are 0 (infinite ratio) or [ 1.0 , inf )
		// the ratio is uploaded / downloaded. less than 1 is not allowed
		void set_ratio(float up_down_ratio) const;

		boost::filesystem::path save_path() const;

		// -1 means unlimited unchokes
		void set_max_uploads(int max_uploads) const;

		// -1 means unlimited connections
		void set_max_connections(int max_connections) const;

		void set_tracker_login(std::string const& name
			, std::string const& password) const;

		// post condition: save_path() == save_path if true is returned
		bool move_storage(boost::filesystem::path const& save_path) const;

		const sha1_hash& info_hash() const
		{ return m_info_hash; }

		bool operator==(const torrent_handle& h) const
		{ return m_info_hash == h.m_info_hash; }

		bool operator!=(const torrent_handle& h) const
		{ return m_info_hash != h.m_info_hash; }

		bool operator<(const torrent_handle& h) const
		{ return m_info_hash < h.m_info_hash; }

	private:

		torrent_handle(aux::session_impl* s,
			aux::checker_impl* c,
			const sha1_hash& h)
			: m_ses(s)
			, m_chk(c)
			, m_info_hash(h)
		{
			assert(m_ses != 0);
		}

#ifndef NDEBUG
		void check_invariant() const;
#endif

		aux::session_impl* m_ses;
		aux::checker_impl* m_chk;
		sha1_hash m_info_hash;

	};

}

#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED
<commit_msg>fixed warning on msvc8<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TORRENT_HANDLE_HPP_INCLUDED
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED

#include <vector>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/date_time/posix_time/posix_time.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/peer_id.hpp"
#include "libtorrent/peer_info.hpp"
#include "libtorrent/piece_picker.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{
	namespace aux
	{
		struct session_impl;
		struct checker_impl;
	}

	struct TORRENT_EXPORT duplicate_torrent: std::exception
	{
		virtual const char* what() const throw()
		{ return "torrent already exists in session"; }
	};

	struct TORRENT_EXPORT invalid_handle: std::exception
	{
		virtual const char* what() const throw()
		{ return "invalid torrent handle used"; }
	};

	struct TORRENT_EXPORT torrent_status
	{
		torrent_status()
			: state(queued_for_checking)
			, paused(false)
			, progress(0.f)
			, total_download(0)
			, total_upload(0)
			, total_payload_download(0)
			, total_payload_upload(0)
			, total_failed_bytes(0)
			, total_redundant_bytes(0)
			, download_rate(0)
			, upload_rate(0)
			, download_payload_rate(0)
			, upload_payload_rate(0)
			, num_peers(0)
			, num_complete(-1)
			, num_incomplete(-1)
			, pieces(0)
			, num_pieces(0)
			, total_done(0)
			, total_wanted_done(0)
			, total_wanted(0)
			, num_seeds(0)
			, distributed_copies(0.f)
			, block_size(0)
		{}

		enum state_t
		{
			queued_for_checking,
			checking_files,
			connecting_to_tracker,
			downloading_metadata,
			downloading,
			finished,
			seeding,
			allocating
		};

		state_t state;
		bool paused;
		float progress;
		boost::posix_time::time_duration next_announce;
		boost::posix_time::time_duration announce_interval;

		std::string current_tracker;

		// transferred this session!
		// total, payload plus protocol
		size_type total_download;
		size_type total_upload;

		// payload only
		size_type total_payload_download;
		size_type total_payload_upload;

		// the amount of payload bytes that
		// has failed their hash test
		size_type total_failed_bytes;

		// the number of payload bytes that
		// has been received redundantly.
		size_type total_redundant_bytes;

		// current transfer rate
		// payload plus protocol
		float download_rate;
		float upload_rate;

		// the rate of payload that is
		// sent and received
		float download_payload_rate;
		float upload_payload_rate;

		// the number of peers this torrent
		// is connected to.
		int num_peers;

		// if the tracker sends scrape info in its
		// announce reply, these fields will be
		// set to the total number of peers that
		// have the whole file and the total number
		// of peers that are still downloading
		int num_complete;
		int num_incomplete;

		const std::vector<bool>* pieces;

		// this is the number of pieces the client has
		// downloaded. it is equal to:
		// std::accumulate(pieces->begin(), pieces->end());
		int num_pieces;

		// the number of bytes of the file we have
		// including pieces that may have been filtered
		// after we downloaded them
		size_type total_done;

		// the number of bytes we have of those that we
		// want. i.e. not counting bytes from pieces that
		// are filtered as not wanted.
		size_type total_wanted_done;

		// the total number of bytes we want to download
		// this may be smaller than the total torrent size
		// in case any pieces are filtered as not wanted
		size_type total_wanted;

		// the number of peers this torrent is connected to
		// that are seeding.
		int num_seeds;

		// the number of distributed copies of the file.
		// note that one copy may be spread out among many peers.
		//
		// the whole number part tells how many copies
		//   there are of the rarest piece(s)
		//
		// the fractional part tells the fraction of pieces that
		//   have more copies than the rarest piece(s).
		float distributed_copies;

		// the block size that is used in this torrent. i.e.
		// the number of bytes each piece request asks for
		// and each bit in the download queue bitfield represents
		int block_size;
	};

	struct TORRENT_EXPORT partial_piece_info
	{
		enum { max_blocks_per_piece = piece_picker::max_blocks_per_piece };
		int piece_index;
		int blocks_in_piece;
		std::bitset<max_blocks_per_piece> requested_blocks;
		std::bitset<max_blocks_per_piece> finished_blocks;
		tcp::endpoint peer[max_blocks_per_piece];
		int num_downloads[max_blocks_per_piece];
	};

	struct TORRENT_EXPORT torrent_handle
	{
		friend class invariant_access;
		friend struct aux::session_impl;
		friend class torrent;

		torrent_handle(): m_ses(0), m_chk(0) {}

		void get_peer_info(std::vector<peer_info>& v) const;
		bool send_chat_message(tcp::endpoint ip, std::string message) const;
		torrent_status status() const;
		void get_download_queue(std::vector<partial_piece_info>& queue) const;

		// fills the specified vector with the download progress [0, 1]
		// of each file in the torrent. The files are ordered as in
		// the torrent_info.
		void file_progress(std::vector<float>& progress);

		std::vector<announce_entry> const& trackers() const;
		void replace_trackers(std::vector<announce_entry> const&) const;

		void add_url_seed(std::string const& url);

		bool has_metadata() const;
		const torrent_info& get_torrent_info() const;
		bool is_valid() const;

		bool is_seed() const;
		bool is_paused() const;
		void pause() const;
		void resume() const;

		// marks the piece with the given index as filtered
		// it will not be downloaded
		void filter_piece(int index, bool filter) const;
		void filter_pieces(std::vector<bool> const& pieces) const;
		bool is_piece_filtered(int index) const;
		std::vector<bool> filtered_pieces() const;

		// marks the file with the given index as filtered
		// it will not be downloaded
		void filter_files(std::vector<bool> const& files) const;

		// set the interface to bind outgoing connections
		// to.
		void use_interface(const char* net_interface) const;

		entry write_resume_data() const;

		// kind of similar to get_torrent_info() but this
		// is lower level, returning the exact info-part of
		// the .torrent file. When hashed, this buffer
		// will produce the info hash. The reference is valid
		// only as long as the torrent is running.
		std::vector<char> const& metadata() const;

		// forces this torrent to reannounce
		// (make a rerequest from the tracker)
		void force_reannounce() const;

		// forces a reannounce in the specified amount of time.
		// This overrides the default announce interval, and no
		// announce will take place until the given time has
		// timed out.
		void force_reannounce(boost::posix_time::time_duration) const;

		// TODO: add a feature where the user can tell the torrent
		// to finish all pieces currently in the pipeline, and then
		// abort the torrent.

		void set_upload_limit(int limit) const;
		void set_download_limit(int limit) const;
		void set_sequenced_download_threshold(int threshold) const;

		void set_peer_upload_limit(tcp::endpoint ip, int limit) const;
		void set_peer_download_limit(tcp::endpoint ip, int limit) const;

		// manually connect a peer
		void connect_peer(tcp::endpoint const& adr) const;

		// valid ratios are 0 (infinite ratio) or [ 1.0 , inf )
		// the ratio is uploaded / downloaded. less than 1 is not allowed
		void set_ratio(float up_down_ratio) const;

		boost::filesystem::path save_path() const;

		// -1 means unlimited unchokes
		void set_max_uploads(int max_uploads) const;

		// -1 means unlimited connections
		void set_max_connections(int max_connections) const;

		void set_tracker_login(std::string const& name
			, std::string const& password) const;

		// post condition: save_path() == save_path if true is returned
		bool move_storage(boost::filesystem::path const& save_path) const;

		const sha1_hash& info_hash() const
		{ return m_info_hash; }

		bool operator==(const torrent_handle& h) const
		{ return m_info_hash == h.m_info_hash; }

		bool operator!=(const torrent_handle& h) const
		{ return m_info_hash != h.m_info_hash; }

		bool operator<(const torrent_handle& h) const
		{ return m_info_hash < h.m_info_hash; }

	private:

		torrent_handle(aux::session_impl* s,
			aux::checker_impl* c,
			const sha1_hash& h)
			: m_ses(s)
			, m_chk(c)
			, m_info_hash(h)
		{
			assert(m_ses != 0);
		}

#ifndef NDEBUG
		void check_invariant() const;
#endif

		aux::session_impl* m_ses;
		aux::checker_impl* m_chk;
		sha1_hash m_info_hash;

	};

}

#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED
<|endoftext|>


<commit_before>/*
 * PThreads.hh
 *
 * Copyright 2002, Emiliano Martin emilianomc@terra.es All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_THREADING_PTHREADS_HH
#define _LOG4CPP_THREADING_PTHREADS_HH

#include <log4cpp/Portability.hh>
#include <stdio.h>
#include <pthread.h>
#include <string>
#include <assert.h>

namespace log4cpp {
    namespace threading {

        /**
         * returns the thread ID
         **/
        static std::string getThreadId() {
            char buffer[16];
            ::sprintf(buffer, "%ld", pthread_self());
            return std::string(buffer);
        }

        /**
         **/
        class Mutex {
            private:
            pthread_mutex_t mutex;

            public:
            inline Mutex() {
                ::pthread_mutex_init(&mutex, NULL);
            }

            inline void lock() {
                ::pthread_mutex_lock(&mutex);
            }

            inline void unlock() {
                ::pthread_mutex_unlock(&mutex);
            }

            inline ~Mutex() {
                ::pthread_mutex_destroy(&mutex);
            }

            inline void operator=(const Mutex &m) {
                mutex = m.mutex;
            }
        };

        /**
         *	definition of ScopedLock;
         **/
        class ScopedLock {
            private:
            Mutex _mutex;

            public:
            inline ScopedLock(const Mutex &mutex) {
                _mutex = mutex;
                _mutex.lock();
            }

            inline ~ScopedLock() {
                _mutex.unlock();
            }
        };

        /**
         *
         **/
        template<typename T> class ThreadLocalDataHolder {
            private:
            pthread_key_t _key;

            public:
            typedef T data_type;

            inline ThreadLocalDataHolder() {
                ::pthread_key_create(&_key, freeHolder);
            }

            inline static void freeHolder(void *p) {
                assert(p != NULL);
                T *data = (T *) p;
                delete p;
            }

            inline ~ThreadLocalDataHolder() {
                T *data = get();
                if (data != NULL) {
                    delete data;
                }
                ::pthread_key_delete(_key);
            }

            inline T* get() const {
                return (T *) ::pthread_getspecific(_key);
            }

            inline T* operator->() const { return get(); }
            inline T& operator*() const { return *get(); }

            inline T* release() {
                T* result = get();
                ::pthread_setspecific(_key, NULL);

                return result;
            }

            inline void reset(T* p = NULL) {
                T *data = get();
                if (data != NULL) {
                    delete data;
                }
                ::pthread_setspecific(_key, p);
            }
        };

    }
}
#endif
<commit_msg>use reinterpret_cast<>.<commit_after>/*
 * PThreads.hh
 *
 * Copyright 2002, Emiliano Martin emilianomc@terra.es All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#ifndef _LOG4CPP_THREADING_PTHREADS_HH
#define _LOG4CPP_THREADING_PTHREADS_HH

#include <log4cpp/Portability.hh>
#include <stdio.h>
#include <pthread.h>
#include <string>
#include <assert.h>

namespace log4cpp {
    namespace threading {

        /**
         * returns the thread ID
         **/
        static std::string getThreadId() {
            char buffer[16];
            ::sprintf(buffer, "%ld", pthread_self());
            return std::string(buffer);
        }

        /**
         **/
        class Mutex {
            private:
            pthread_mutex_t mutex;

            public:
            inline Mutex() {
                ::pthread_mutex_init(&mutex, NULL);
            }

            inline void lock() {
                ::pthread_mutex_lock(&mutex);
            }

            inline void unlock() {
                ::pthread_mutex_unlock(&mutex);
            }

            inline ~Mutex() {
                ::pthread_mutex_destroy(&mutex);
            }

            inline void operator=(const Mutex &m) {
                mutex = m.mutex;
            }
        };

        /**
         *	definition of ScopedLock;
         **/
        class ScopedLock {
            private:
            Mutex _mutex;

            public:
            inline ScopedLock(const Mutex &mutex) {
                _mutex = mutex;
                _mutex.lock();
            }

            inline ~ScopedLock() {
                _mutex.unlock();
            }
        };

        /**
         *
         **/
        template<typename T> class ThreadLocalDataHolder {
            private:
            pthread_key_t _key;

            public:
            typedef T data_type;

            inline ThreadLocalDataHolder() {
                ::pthread_key_create(&_key, freeHolder);
            }

            inline static void freeHolder(void *p) {
                assert(p != NULL);
                delete reinterpret_cast<T *>(p);
             }

            inline ~ThreadLocalDataHolder() {
                T *data = get();
                if (data != NULL) {
                    delete data;
                }
                ::pthread_key_delete(_key);
            }

            inline T* get() const {
                return reinterpret_cast<T *>(::pthread_getspecific(_key));
            }

            inline T* operator->() const { return get(); }
            inline T& operator*() const { return *get(); }

            inline T* release() {
                T* result = get();
                ::pthread_setspecific(_key, NULL);

                return result;
            }

            inline void reset(T* p = NULL) {
                T *data = get();
                if (data != NULL) {
                    delete data;
                }
                ::pthread_setspecific(_key, p);
            }
        };

    }
}
#endif
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkXRenderWindowInteractor.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkXRenderWindowInteractor - an X event driven interface for a RenderWindow
// .SECTION Description
// vtkXRenderWindowInteractor is a convenience object that provides
// event bindings to common graphics functions. For example, camera
// zoom-in/zoom-out, azimuth, and roll. It is one of the window system
// specific subclasses of vtkRenderWindowInteractor.

// .SECTION see also
// vtkRenderWindowInteractor vtkXRenderWindow

// .SECTION Event Bindings
// Mouse bindings: Button 1 - rotate, Button 2 - pan, Button 3 - zoom
// The distance from the center of the renderer viewport determines
// how quickly to rotate, pan and zoom.
// Keystrokes:
//    r - reset camera view
//    w - turn all actors wireframe
//    s - turn all actors surface
//    e - exits

#ifndef __vtkXRenderWindowInteractor_h
#define __vtkXRenderWindowInteractor_h

//===========================================================
// now we define the C++ class

#include "vtkRenderWindowInteractor.hh"
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>

class vtkXRenderWindowInteractor : public vtkRenderWindowInteractor
{
public:
  vtkXRenderWindowInteractor();
  ~vtkXRenderWindowInteractor();
  char *GetClassName() {return "vtkXRenderWindowInteractor";};
  void PrintSelf(ostream& os, vtkIndent indent);

  virtual void Initialize();
  virtual void Initialize(XtAppContext app);
  virtual void Start();
  void UpdateSize(int,int);
  void StartRotate();
  void EndRotate();
  void StartZoom();
  void EndZoom();
  void StartPan();
  void EndPan();
  void SetWidget(Widget);
  void SetupNewWindow(int Stereo = 0);
  void FinishSettingUpNewWindow();

  friend void vtkXRenderWindowInteractorCallback(Widget,XtPointer,
					     XEvent *,Boolean *);
  friend void vtkXRenderWindowInteractorTimer(XtPointer,XtIntervalId *);

protected:
  Display *DisplayId;
  Window WindowId;
  Widget top;
  Widget oldTop;
  XtAppContext App;
  int PositionBeforeStereo[2];
};

#endif

<commit_msg>*** empty log message ***<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXRenderWindowInteractor.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkXRenderWindowInteractor - an X event driven interface for a RenderWindow
// .SECTION Description
// vtkXRenderWindowInteractor is a convenience object that provides
// event bindings to common graphics functions. For example, camera
// zoom-in/zoom-out, azimuth, and roll. It is one of the window system
// specific subclasses of vtkRenderWindowInteractor.

// .SECTION see also
// vtkRenderWindowInteractor vtkXRenderWindow

// .SECTION Event Bindings
// Mouse bindings: Button 1 - rotate, Button 2 - pan, Button 3 - zoom
// The distance from the center of the renderer viewport determines
// how quickly to rotate, pan and zoom.
// Keystrokes:
//    r - reset camera view
//    w - turn all actors wireframe
//    s - turn all actors surface
//    u - execute user defined function
//    p - pick actor under mouse pointer (if pickable)
//    3 - toggle in/out of 3D mode (if supported by renderer)
//    e - exit

#ifndef __vtkXRenderWindowInteractor_h
#define __vtkXRenderWindowInteractor_h

//===========================================================
// now we define the C++ class

#include "vtkRenderWindowInteractor.hh"
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>

class vtkXRenderWindowInteractor : public vtkRenderWindowInteractor
{
public:
  vtkXRenderWindowInteractor();
  ~vtkXRenderWindowInteractor();
  char *GetClassName() {return "vtkXRenderWindowInteractor";};
  void PrintSelf(ostream& os, vtkIndent indent);

  virtual void Initialize();
  virtual void Initialize(XtAppContext app);
  virtual void Start();
  void UpdateSize(int,int);
  void StartRotate();
  void EndRotate();
  void StartZoom();
  void EndZoom();
  void StartPan();
  void EndPan();
  void SetWidget(Widget);
  void SetupNewWindow(int Stereo = 0);
  void FinishSettingUpNewWindow();

  friend void vtkXRenderWindowInteractorCallback(Widget,XtPointer,
					     XEvent *,Boolean *);
  friend void vtkXRenderWindowInteractorTimer(XtPointer,XtIntervalId *);

protected:
  Display *DisplayId;
  Window WindowId;
  Widget top;
  Widget oldTop;
  XtAppContext App;
  int PositionBeforeStereo[2];
};

#endif

<|endoftext|>


<commit_before>#ifndef LYZA_FUNCTIONAL_VARIANT__
# define LYZA_FUNCTIONAL_VARIANT__

# include <stdexcept>
# include <tuple>
# include <typeinfo>
# include <type_traits>
# include <functional>
# include <utility>

# include "mp/union.hpp"
# include "mp/tlist.hpp"

namespace lyza { namespace functional {

typedef void dummy;

template <typename ...Targs>
class variant {
    template <size_t Tn, typename Tdummy>
    struct deduce_copy {
        static inline void copy(size_t n, variant& a, variant const& b)
        {
            if (Tn == n) {
				typedef typename n_to_type<Tn>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = b.unsafe_get<type>();
				a.tag_ = b.tag_;
            } else {
                deduce_copy<Tn - 1, Tdummy>::copy(n, a, b);
            }
        }

        static inline void copy(size_t n, variant& a, variant&& b)
        {
            if (Tn == n) {
				typedef typename n_to_type<Tn>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = std::move(b.unsafe_get<type>());
				a.tag_ = b.tag_;
            } else {
                deduce_copy<Tn - 1, Tdummy>::copy(n, a, b);
            }
        }
    };

    template <typename Tdummy>
    struct deduce_copy<0, Tdummy> {
        static inline void copy(size_t n, variant& a, variant const& b)
        {
            if (n == 0) {
				typedef typename n_to_type<0>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = b.unsafe_get<type>();
				a.tag_ = b.tag_;
            }
        }

        static inline void copy(size_t n, variant& a, variant&& b)
        {
            if (n == 0) {
				typedef typename n_to_type<0>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = std::move(b.unsafe_get<type>());
				a.tag_ = b.tag_;
            }
        }
    };

    public:
        void copy(variant const& v)
        {
            deduce_copy<mp::tlist_length<tlist__>::value - 1, dummy>::copy(v.tag_, *this, v);
        }

        void copy(variant&& v)
        {
            deduce_copy<mp::tlist_length<tlist__>::value - 1, dummy>::copy(v.tag_, *this, std::forward(v));
        }

        template <typename T>
        variant(T&& t)
            : tag_(tag<T>::value), v_()
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = std::move(t);
        }

        template <typename T>
        variant(T const& t)
            : tag_(tag<T>::value), v_()
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = t;
        }

        variant(variant const& v)
            : tag_(v.tag_), v_()
        {
            copy(v);
        }

        variant(variant&& v)
            : tag_(v.tag_), v_()
        {
            copy(v);
        }

        template <typename T>
        variant& operator=(T&& t)
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = std::move(t);
            tag_ = tag<T>::value;
            return *this;
        }

        template <typename T>
        variant& operator=(T const& t)
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = t;
            tag_ = tag<T>::value;
            return *this;
        }

        variant& operator=(variant&& v)
        {
			copy(v);
            return *this;
        }

        variant& operator=(variant const& v)
        {
			copy(v);
			return *this;
        }

        template <typename T>
        bool isa() const
        {
            return tag<T>::value == tag_;
        }

        template <typename Tret>
        static Tret otherwise(variant& v)
        {
            throw std::runtime_error("type matching failed");
        }

        template <typename T, typename Tret>
        Tret match(
                std::function<Tret (T&)> const& f,
                std::function<Tret (variant&)> const& fo = &variant::otherwise<Tret>
                )
        {
            if (isa<T>())
                return f(unsafe_get<T>());
            return fo(*this);
        }

        template <typename T>
        void match(
                std::function<void (T&)> const& f,
                std::function<void (variant&)> const& fo = &variant::otherwise<void>
                )
        {
            if (isa<T>())
                f(unsafe_get<T>());
            else
                fo(*this);
        }

        size_t get_current_tag() const
        {
            return tag_;
        }

    public:
        typedef
            typename mp::make_tlist<Targs...>::type
            tlist__;

        typedef
            typename mp::make_union<Targs...>::type
            union__;

        template <typename T>
        struct type_matcher {
            template <typename U>
            struct match {
                enum { value = std::is_same<T, U>::value };
            };
        };

        template <size_t Tn>
        struct n_to_type {
            typedef
                typename lyza::mp::union_nth<union__, Tn>::type
                type;
        };

    private:
        template <size_t Tn, typename Tvisitor>
        struct deduce_visit {
            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant& v)
            {
                if (Tn == n) {
                    return vt(v.unsafe_get<typename n_to_type<Tn>::type>());
                }
				return deduce_visit<Tn - 1, Tvisitor>::visit(n, vt, v);
            }

            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant const& v)
            {
                if (Tn == n) {
                    return vt(v.unsafe_get<typename n_to_type<Tn>::type>());
                }
				return deduce_visit<Tn - 1, Tvisitor>::visit(n, vt, v);
            }
        };

        template <typename Tvisitor>
        struct deduce_visit<0, Tvisitor> {
            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant& v)
            {
                if (n == 0) {
                    return vt(v.unsafe_get<typename n_to_type<0>::type>());
                }
				throw std::runtime_error("invalid visit");
            }

            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant const& v)
            {
                if (n == 0) {
                    return vt(v.unsafe_get<typename n_to_type<0>::type>());
                }
				throw std::runtime_error("invalid visit");
            }
        };

    public:
        template <typename Tvisitor>
		typename Tvisitor::ret_type
			apply_visitor(Tvisitor const& vt)
        {
            return deduce_visit<mp::tlist_length<tlist__>::value - 1, Tvisitor>::visit(tag_, vt, *this);
        }

        template <typename Tvisitor>
		typename Tvisitor::ret_type
			apply_visitor(Tvisitor const& vt) const
        {
            return deduce_visit<mp::tlist_length<tlist__>::value - 1, Tvisitor>::visit(tag_, vt, *this);
        }

    public:
        template <typename T>
        struct tag {
            enum { value = lyza::mp::find_count<tlist__, type_matcher<T> >::value };
        };

    private:
        template <typename T>
        struct mp_union
        : public
          lyza::mp::union_nth<
                union__,
                lyza::mp::find_count<tlist__, type_matcher<typename std::remove_reference<T>::type> >::value
          > {};

    public:
        template <typename T>
        const typename mp_union<T>::type&
        unsafe_get() const
        {
            return mp_union<T>::get(v_);
        }

        template <typename T>
        typename mp_union<T>::type&
        unsafe_get()
        {
            return mp_union<T>::get(v_);
        }

        template <typename T>
        const typename mp_union<T>::type&
        get() const
        {
            if (isa<T>())
                return mp_union<T>::get(v_);
            throw std::bad_cast();
        }

        template <typename T>
        typename mp_union<T>::type&
        get()
        {
            if (isa<T>())
                return mp_union<T>::get(v_);
            throw std::bad_cast();
        }

    protected:
        size_t tag_;
        typename union__::type v_;
};

}}

#endif
<commit_msg>Fix invalid tag value (due to universal reference)<commit_after>#ifndef LYZA_FUNCTIONAL_VARIANT__
# define LYZA_FUNCTIONAL_VARIANT__

# include <stdexcept>
# include <tuple>
# include <typeinfo>
# include <type_traits>
# include <functional>
# include <utility>

# include "mp/union.hpp"
# include "mp/tlist.hpp"

namespace lyza { namespace functional {

typedef void dummy;

template <typename ...Targs>
class variant {
    template <size_t Tn, typename Tdummy>
    struct deduce_copy {
        static inline void copy(size_t n, variant& a, variant const& b)
        {
            if (Tn == n) {
				typedef typename n_to_type<Tn>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = b.unsafe_get<type>();
				a.tag_ = b.tag_;
            } else {
                deduce_copy<Tn - 1, Tdummy>::copy(n, a, b);
            }
        }

        static inline void copy(size_t n, variant& a, variant&& b)
        {
            if (Tn == n) {
				typedef typename n_to_type<Tn>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = std::move(b.unsafe_get<type>());
				a.tag_ = b.tag_;
            } else {
                deduce_copy<Tn - 1, Tdummy>::copy(n, a, b);
            }
        }
    };

    template <typename Tdummy>
    struct deduce_copy<0, Tdummy> {
        static inline void copy(size_t n, variant& a, variant const& b)
        {
            if (n == 0) {
				typedef typename n_to_type<0>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = b.unsafe_get<type>();
				a.tag_ = b.tag_;
            }
        }

        static inline void copy(size_t n, variant& a, variant&& b)
        {
            if (n == 0) {
				typedef typename n_to_type<0>::type type;

				type& afield = a.unsafe_get<type>();
				new (&afield) type();
				afield = std::move(b.unsafe_get<type>());
				a.tag_ = b.tag_;
            }
        }
    };

    public:
        void copy(variant const& v)
        {
            deduce_copy<mp::tlist_length<tlist__>::value - 1, dummy>::copy(v.tag_, *this, v);
        }

        void copy(variant&& v)
        {
            deduce_copy<mp::tlist_length<tlist__>::value - 1, dummy>::copy(v.tag_, *this, std::forward(v));
        }

        template <typename T>
        variant(T&& t)
            : tag_(tag< typename std::remove_reference<T>::type >::value), v_()
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = std::move(t);
        }

        template <typename T>
        variant(T const& t)
            : tag_(tag<T>::value), v_()
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = t;
        }

        variant(variant const& v)
            : tag_(v.tag_), v_()
        {
            copy(v);
        }

        variant(variant&& v)
            : tag_(v.tag_), v_()
        {
            copy(v);
        }

        template <typename T>
        variant& operator=(T&& t)
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = std::move(t);
            tag_ = tag<T>::value;
            return *this;
        }

        template <typename T>
        variant& operator=(T const& t)
        {
			T& field = mp_union<T>::get(v_);
			new (&field) typename std::remove_reference<T>::type();

            field = t;
            tag_ = tag<T>::value;
            return *this;
        }

        variant& operator=(variant&& v)
        {
			copy(v);
            return *this;
        }

        variant& operator=(variant const& v)
        {
			copy(v);
			return *this;
        }

        template <typename T>
        bool isa() const
        {
            return tag<T>::value == tag_;
        }

        template <typename Tret>
        static Tret otherwise(variant& v)
        {
            throw std::runtime_error("type matching failed");
        }

        template <typename T, typename Tret>
        Tret match(
                std::function<Tret (T&)> const& f,
                std::function<Tret (variant&)> const& fo = &variant::otherwise<Tret>
                )
        {
            if (isa<T>())
                return f(unsafe_get<T>());
            return fo(*this);
        }

        template <typename T>
        void match(
                std::function<void (T&)> const& f,
                std::function<void (variant&)> const& fo = &variant::otherwise<void>
                )
        {
            if (isa<T>())
                f(unsafe_get<T>());
            else
                fo(*this);
        }

        size_t get_current_tag() const
        {
            return tag_;
        }

    public:
        typedef
            typename mp::make_tlist<Targs...>::type
            tlist__;

        typedef
            typename mp::make_union<Targs...>::type
            union__;

        template <typename T>
        struct type_matcher {
            template <typename U>
            struct match {
                enum { value = std::is_same<T, U>::value };
            };
        };

        template <size_t Tn>
        struct n_to_type {
            typedef
                typename lyza::mp::union_nth<union__, Tn>::type
                type;
        };

    private:
        template <size_t Tn, typename Tvisitor>
        struct deduce_visit {
            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant& v)
            {
                if (Tn == n) {
                    return vt(v.unsafe_get<typename n_to_type<Tn>::type>());
                }
				return deduce_visit<Tn - 1, Tvisitor>::visit(n, vt, v);
            }

            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant const& v)
            {
                if (Tn == n) {
                    return vt(v.unsafe_get<typename n_to_type<Tn>::type>());
                }
				return deduce_visit<Tn - 1, Tvisitor>::visit(n, vt, v);
            }
        };

        template <typename Tvisitor>
        struct deduce_visit<0, Tvisitor> {
            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant& v)
            {
                if (n == 0) {
                    return vt(v.unsafe_get<typename n_to_type<0>::type>());
                }
				throw std::runtime_error("invalid visit");
            }

            static inline
				typename Tvisitor::ret_type
				visit(size_t n, Tvisitor const& vt, variant const& v)
            {
                if (n == 0) {
                    return vt(v.unsafe_get<typename n_to_type<0>::type>());
                }
				throw std::runtime_error("invalid visit");
            }
        };

    public:
        template <typename Tvisitor>
		typename Tvisitor::ret_type
			apply_visitor(Tvisitor const& vt)
        {
            return deduce_visit<mp::tlist_length<tlist__>::value - 1, Tvisitor>::visit(tag_, vt, *this);
        }

        template <typename Tvisitor>
		typename Tvisitor::ret_type
			apply_visitor(Tvisitor const& vt) const
        {
            return deduce_visit<mp::tlist_length<tlist__>::value - 1, Tvisitor>::visit(tag_, vt, *this);
        }

    public:
        template <typename T>
        struct tag {
            enum { value = lyza::mp::find_count<tlist__, type_matcher<T> >::value };
        };

    private:
        template <typename T>
        struct mp_union
        : public
          lyza::mp::union_nth<
                union__,
                lyza::mp::find_count<tlist__, type_matcher<typename std::remove_reference<T>::type> >::value
          > {};

    public:
        template <typename T>
        const typename mp_union<T>::type&
        unsafe_get() const
        {
            return mp_union<T>::get(v_);
        }

        template <typename T>
        typename mp_union<T>::type&
        unsafe_get()
        {
            return mp_union<T>::get(v_);
        }

        template <typename T>
        const typename mp_union<T>::type&
        get() const
        {
            if (isa<T>())
                return mp_union<T>::get(v_);
            throw std::bad_cast();
        }

        template <typename T>
        typename mp_union<T>::type&
        get()
        {
            if (isa<T>())
                return mp_union<T>::get(v_);
            throw std::bad_cast();
        }

    protected:
        size_t tag_;
        typename union__::type v_;
};

}}

#endif
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>
#include <vector>
#include <atomic>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "assert.hpp"
#include "Options.hpp"

using namespace eddic;

namespace po = boost::program_options;

namespace {

std::pair<std::string, std::string> numeric_parser(const std::string& s){
    if (s.find("-32") == 0) {
        return make_pair("32", std::string("true"));
    } else if (s.find("-64") == 0) {
        return make_pair("64", std::string("true"));
    } else {
        return make_pair(std::string(), std::string());
    }
}

std::atomic<bool> description_flag;

po::options_description visible("Usage : eddic [options] source.eddi");
po::options_description all("Usage : eddic [options] source.eddi");

std::unordered_map<std::string, std::vector<std::string>> triggers;

void add_trigger(const std::string& option, const std::vector<std::string>& childs){
   triggers[option] = childs;
}

void init_descriptions(){
    po::options_description general("General options");
    general.add_options()
        ("help,h", "Generate this help message")
        ("assembly,S", "Generate only the assembly")
        ("keep,k", "Keep the assembly file")
        ("version", "Print the version of eddic")
        ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

        ("debug,g", "Add debugging symbols")

        ("template-depth", po::value<int>()->default_value(100), "Define the maximum template depth")

        ("32", "Force the compilation for 32 bits platform")
        ("64", "Force the compilation for 64 bits platform")

        ("warning-all", "Enable all the warning messages")
        ("warning-unused", "Warn about unused variables, parameters and functions")
        ("warning-cast", "Warn about useless casts")
        ("warning-effects", "Warn about statements without effect")
        ;

    po::options_description display("Display options");
    display.add_options()
        ("ast", "Print the Abstract Syntax Tree representation of the source")
        ("ast-raw", "Print the Abstract Syntax Tree representation of the source coming directly from the parser before any pass is run on the AST. ")
        ("ast-only", "Only print the Abstract Syntax Tree representation of the source (do not continue compilation after printing)")

        ("mtac", "Print the medium-level Three Address Code representation of the source")
        ("mtac-opt", "Print the medium-level Three Address Code representation of the source before any optimization has been performed")
        ("mtac-only", "Only print the medium-level Three Address Code representation of the source (do not continue compilation after printing)")

        ("ltac-pre", "Print the low-level Three Address Code representation of the source before allocation of registers")
        ("ltac-alloc", "Print the low-level Three Address Code representation of the source before optimization")
        ("ltac", "Print the final low-level Three Address Code representation of the source")
        ("ltac-only", "Only print the low-level Three Address Code representation of the source (do not continue compilation after printing)")
        ;

    po::options_description optimization("Optimization options");
    optimization.add_options()
        ("Opt,O", po::value<int>()->implicit_value(0)->default_value(2), "Define the optimization level")
        ("O0", "Disable all optimizations")
        ("O1", "Enable low-level optimizations")
        ("O2", "Enable all optimizations. This can be slow for big programs.")

        ("fglobal-optimization", "Enable optimizer engine")
        ("fparameter-allocation", "Enable parameter allocation in register")
        ("fpeephole-optimization", "Enable peephole optimizer")
        ("fomit-frame-pointer", "Omit frame pointer from functions")
        ("finline-functions", "Enable inlining")
        ("fno-inline-functions", "Disable inlining")
        ;

    po::options_description backend("Backend options");
    backend.add_options()
        ("log", po::value<int>()->default_value(0), "Define the logging")
        ("quiet,q", "Do not print anything")
        ("verbose,v", "Make the compiler verbose")
        ("single-threaded", "Disable the multi-threaded optimization")
        ("time", "Activate the timing system")
        ("stats", "Activate the statistics system")
        ("input", po::value<std::string>(), "Input file")
        ;

    all.add(general).add(display).add(optimization).add(backend);
    visible.add(general).add(display).add(optimization);

    add_trigger("warning-all", {"warning-unused", "warning-cast", "warning-effects"});

    //Special triggers for optimization levels
    add_trigger("__1", {"fpeephole-optimization"});
    add_trigger("__2", {"fglobal-optimization", "fomit-frame-pointer", "fparameter-allocation", "finline-functions"});
}

inline void trigger_childs(std::shared_ptr<Configuration> configuration, const std::vector<std::string>& childs){
    for(auto& child : childs){
        configuration->values[child].defined = true;
        configuration->values[child].value = std::string("true");
    }
}

} //end of anonymous namespace

std::shared_ptr<Configuration> eddic::parseOptions(int argc, const char* argv[]) {
    //Create a new configuration
    auto configuration = std::make_shared<Configuration>();

    try {
        //Only if the description has not been already defined
        if(!description_flag.load()){
            bool old_value = description_flag.load();
            if(description_flag.compare_exchange_strong(old_value, true)){
                init_descriptions();
            }
        }

        //Add the option of the input file
        po::positional_options_description p;
        p.add("input", -1);

        //Create a new set of options
        po::variables_map options;

        //Parse the command line options
        po::store(po::command_line_parser(argc, argv).options(all).extra_parser(numeric_parser).positional(p).run(), options);
        po::notify(options);

        //Transfer the options in the eddic configuration
        for(auto& option : all.options()){
            ConfigValue value;

            if(options.count(option->long_name())){
                value.defined = true;
                value.value = options[option->long_name()].value();
            } else {
                value.defined = false;
                value.value = std::string("false");
            }

            configuration->values[option->long_name()] = value;
        }

        if(options.count("O0") + options.count("O1") + options.count("O2") > 1){
            std::cout << "Invalid command line options : only one optimization level should be set" << std::endl;

            return nullptr;
        }

        if(options.count("64") && options.count("32")){
            std::cout << "Invalid command line options : a compilation cannot be both 32 and 64 bits" << std::endl;

            return nullptr;
        }

        //Update optimization level based on special switches
        if(options.count("O0")){
            configuration->values["Opt"].value = 0;
        } else if(options.count("O1")){
            configuration->values["Opt"].value = 1;
        } else if(options.count("O2")){
            configuration->values["Opt"].value = 2;
        }

        //Triggers dependent options
        for(auto& trigger : triggers){
            if(configuration->option_defined(trigger.first)){
                trigger_childs(configuration, trigger.second);
            }
        }

        if(configuration->option_int_value("Opt") >= 1){
            trigger_childs(configuration, triggers["__1"]);
        }

        if(configuration->option_int_value("Opt") >= 2){
            trigger_childs(configuration, triggers["__2"]);
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return nullptr;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return nullptr;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return nullptr;
    }

    return configuration;
}

bool Configuration::option_defined(const std::string& option_name){
    return values[option_name].defined;
}

std::string Configuration::option_value(const std::string& option_name){
    return boost::any_cast<std::string>(values[option_name].value);
}

int Configuration::option_int_value(const std::string& option_name){
    return boost::any_cast<int>(values[option_name].value);
}

void eddic::print_help(){
    std::cout << visible << std::endl;
}

void eddic::print_version(){
    std::cout << "eddic version 1.2.0" << std::endl;
}
<commit_msg>Add a new option to detect useless includes<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>
#include <vector>
#include <atomic>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "assert.hpp"
#include "Options.hpp"

using namespace eddic;

namespace po = boost::program_options;

namespace {

std::pair<std::string, std::string> numeric_parser(const std::string& s){
    if (s.find("-32") == 0) {
        return make_pair("32", std::string("true"));
    } else if (s.find("-64") == 0) {
        return make_pair("64", std::string("true"));
    } else {
        return make_pair(std::string(), std::string());
    }
}

std::atomic<bool> description_flag;

po::options_description visible("Usage : eddic [options] source.eddi");
po::options_description all("Usage : eddic [options] source.eddi");

std::unordered_map<std::string, std::vector<std::string>> triggers;

void add_trigger(const std::string& option, const std::vector<std::string>& childs){
   triggers[option] = childs;
}

void init_descriptions(){
    po::options_description general("General options");
    general.add_options()
        ("help,h", "Generate this help message")
        ("assembly,S", "Generate only the assembly")
        ("keep,k", "Keep the assembly file")
        ("version", "Print the version of eddic")
        ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

        ("debug,g", "Add debugging symbols")

        ("template-depth", po::value<int>()->default_value(100), "Define the maximum template depth")

        ("32", "Force the compilation for 32 bits platform")
        ("64", "Force the compilation for 64 bits platform")

        ("warning-all", "Enable all the warning messages")
        ("warning-unused", "Warn about unused variables, parameters and functions")
        ("warning-cast", "Warn about useless casts")
        ("warning-effects", "Warn about statements without effect")
        ("warning-includes", "Warn about useless includes")
        ;

    po::options_description display("Display options");
    display.add_options()
        ("ast", "Print the Abstract Syntax Tree representation of the source")
        ("ast-raw", "Print the Abstract Syntax Tree representation of the source coming directly from the parser before any pass is run on the AST. ")
        ("ast-only", "Only print the Abstract Syntax Tree representation of the source (do not continue compilation after printing)")

        ("mtac", "Print the medium-level Three Address Code representation of the source")
        ("mtac-opt", "Print the medium-level Three Address Code representation of the source before any optimization has been performed")
        ("mtac-only", "Only print the medium-level Three Address Code representation of the source (do not continue compilation after printing)")

        ("ltac-pre", "Print the low-level Three Address Code representation of the source before allocation of registers")
        ("ltac-alloc", "Print the low-level Three Address Code representation of the source before optimization")
        ("ltac", "Print the final low-level Three Address Code representation of the source")
        ("ltac-only", "Only print the low-level Three Address Code representation of the source (do not continue compilation after printing)")
        ;

    po::options_description optimization("Optimization options");
    optimization.add_options()
        ("Opt,O", po::value<int>()->implicit_value(0)->default_value(2), "Define the optimization level")
        ("O0", "Disable all optimizations")
        ("O1", "Enable low-level optimizations")
        ("O2", "Enable all optimizations. This can be slow for big programs.")

        ("fglobal-optimization", "Enable optimizer engine")
        ("fparameter-allocation", "Enable parameter allocation in register")
        ("fpeephole-optimization", "Enable peephole optimizer")
        ("fomit-frame-pointer", "Omit frame pointer from functions")
        ("finline-functions", "Enable inlining")
        ("fno-inline-functions", "Disable inlining")
        ;

    po::options_description backend("Backend options");
    backend.add_options()
        ("log", po::value<int>()->default_value(0), "Define the logging")
        ("quiet,q", "Do not print anything")
        ("verbose,v", "Make the compiler verbose")
        ("single-threaded", "Disable the multi-threaded optimization")
        ("time", "Activate the timing system")
        ("stats", "Activate the statistics system")
        ("input", po::value<std::string>(), "Input file")
        ;

    all.add(general).add(display).add(optimization).add(backend);
    visible.add(general).add(display).add(optimization);

    add_trigger("warning-all", {"warning-unused", "warning-cast", "warning-effects", "warning-includes"});

    //Special triggers for optimization levels
    add_trigger("__1", {"fpeephole-optimization"});
    add_trigger("__2", {"fglobal-optimization", "fomit-frame-pointer", "fparameter-allocation", "finline-functions"});
}

inline void trigger_childs(std::shared_ptr<Configuration> configuration, const std::vector<std::string>& childs){
    for(auto& child : childs){
        configuration->values[child].defined = true;
        configuration->values[child].value = std::string("true");
    }
}

} //end of anonymous namespace

std::shared_ptr<Configuration> eddic::parseOptions(int argc, const char* argv[]) {
    //Create a new configuration
    auto configuration = std::make_shared<Configuration>();

    try {
        //Only if the description has not been already defined
        if(!description_flag.load()){
            bool old_value = description_flag.load();
            if(description_flag.compare_exchange_strong(old_value, true)){
                init_descriptions();
            }
        }

        //Add the option of the input file
        po::positional_options_description p;
        p.add("input", -1);

        //Create a new set of options
        po::variables_map options;

        //Parse the command line options
        po::store(po::command_line_parser(argc, argv).options(all).extra_parser(numeric_parser).positional(p).run(), options);
        po::notify(options);

        //Transfer the options in the eddic configuration
        for(auto& option : all.options()){
            ConfigValue value;

            if(options.count(option->long_name())){
                value.defined = true;
                value.value = options[option->long_name()].value();
            } else {
                value.defined = false;
                value.value = std::string("false");
            }

            configuration->values[option->long_name()] = value;
        }

        if(options.count("O0") + options.count("O1") + options.count("O2") > 1){
            std::cout << "Invalid command line options : only one optimization level should be set" << std::endl;

            return nullptr;
        }

        if(options.count("64") && options.count("32")){
            std::cout << "Invalid command line options : a compilation cannot be both 32 and 64 bits" << std::endl;

            return nullptr;
        }

        //Update optimization level based on special switches
        if(options.count("O0")){
            configuration->values["Opt"].value = 0;
        } else if(options.count("O1")){
            configuration->values["Opt"].value = 1;
        } else if(options.count("O2")){
            configuration->values["Opt"].value = 2;
        }

        //Triggers dependent options
        for(auto& trigger : triggers){
            if(configuration->option_defined(trigger.first)){
                trigger_childs(configuration, trigger.second);
            }
        }

        if(configuration->option_int_value("Opt") >= 1){
            trigger_childs(configuration, triggers["__1"]);
        }

        if(configuration->option_int_value("Opt") >= 2){
            trigger_childs(configuration, triggers["__2"]);
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return nullptr;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return nullptr;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return nullptr;
    }

    return configuration;
}

bool Configuration::option_defined(const std::string& option_name){
    return values[option_name].defined;
}

std::string Configuration::option_value(const std::string& option_name){
    return boost::any_cast<std::string>(values[option_name].value);
}

int Configuration::option_int_value(const std::string& option_name){
    return boost::any_cast<int>(values[option_name].value);
}

void eddic::print_help(){
    std::cout << visible << std::endl;
}

void eddic::print_version(){
    std::cout << "eddic version 1.2.0" << std::endl;
}
<|endoftext|>


<commit_before>#include "log.hpp"
#include "boost_root.hpp"
#include "temporary.hpp"
#include "cdm_boost.hpp"
#include "cdm/cmake_generator.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <cdm/locate_cache.hpp>
#include <ventura/cmake.hpp>
#include <boost/algorithm/string/split.hpp>

namespace
{
	ventura::absolute_path const this_file = *ventura::absolute_path::create(__FILE__);
	ventura::absolute_path const test = *ventura::parent(this_file);
	ventura::absolute_path const repository = *ventura::parent(test);
}

BOOST_AUTO_TEST_CASE(test_using_cppnetlib_v2)
{
	cdm::travis_keep_alive_printer keep_travis_alive;
	ventura::absolute_path const app_source = repository / "application/using_cppnetlib_v2";
	ventura::absolute_path const app_cdm_source = app_source / "cdm";
	ventura::absolute_path const tmp = cdm::get_temporary_root_for_testing() / "cdm";
	ventura::absolute_path const module_temporaries = tmp / "mod";
	ventura::absolute_path const application_build_dir = tmp / "using_cppnetlib_v2";
	ventura::recreate_directories(module_temporaries, Si::throw_);
	ventura::recreate_directories(application_build_dir, Si::throw_);
	std::unique_ptr<std::ofstream> log_file = cdm::open_log(application_build_dir / "test_using_cppnetlib_v2.txt");
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(*log_file));
	ventura::absolute_path const build_configure = module_temporaries / "build_configure";
	ventura::recreate_directories(build_configure, Si::throw_);
	{
		std::vector<Si::noexcept_string> arguments;
		{
			ventura::absolute_path const include = repository / "dependencies/silicium";
			arguments.emplace_back("-DSILICIUM_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		{
			ventura::absolute_path const include = repository / "dependencies/ventura";
			arguments.emplace_back("-DVENTURA_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		Si::optional<ventura::absolute_path> const boost_root = cdm::get_boost_root_for_testing();
		if (boost_root)
		{
			cdm::generate_cmake_definitions_for_using_boost(Si::make_container_sink(arguments), *boost_root);
#if CDM_TESTS_RUNNING_ON_APPVEYOR
			arguments.emplace_back("-DBOOST_LIBRARYDIR=" + ventura::to_utf8_string(*boost_root / "lib32-msvc-14.0"));
#endif
		}
		ventura::absolute_path const modules = repository / "modules";
		arguments.emplace_back("-DCDM_CONFIGURE_INCLUDE_DIRS=" + ventura::to_utf8_string(modules) + ";" +
		                       ventura::to_utf8_string(repository));
		arguments.emplace_back(ventura::to_utf8_string(app_cdm_source));
		cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		Si::noexcept_string generated_cmake_arguments;
		{
			std::vector<Si::noexcept_string> arguments;
			ventura::relative_path const relative(
#ifdef _WIN32
			    "Debug/"
#endif
			    "configure"
#ifdef _WIN32
			    ".exe"
#endif
			    );
			auto configure_sink =
			    Si::Sink<char, Si::success>::erase(Si::make_container_sink(generated_cmake_arguments));
			ventura::process_parameters parameters;
			parameters.executable = build_configure / relative;
			parameters.arguments = ventura::arguments_to_os_strings(arguments);
			parameters.current_path = build_configure;
			auto console_output = cdm::make_program_output_printer(Si::ostream_ref_sink(std::cerr));
			parameters.err = &console_output;
			parameters.out = &configure_sink;
			BOOST_REQUIRE_EQUAL(0, ventura::run_process(parameters));
			BOOST_REQUIRE(!generated_cmake_arguments.empty());
		}

		{
			std::vector<Si::noexcept_string> arguments;
			boost::algorithm::split(arguments, generated_cmake_arguments, [](char c)
			                        {
				                        return c >= 0 && c <= ' ';
				                    });
			BOOST_REQUIRE(!arguments.empty());
			BOOST_REQUIRE(arguments.back().empty());
			arguments.pop_back();
			cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
			BOOST_REQUIRE_EQUAL(0,
			                    ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
			                                         std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
			                                         ventura::environment_inheritance::inherit).get());
		}
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::os_string> arguments;
		ventura::relative_path const relative(
#ifdef _WIN32
		    "Debug/"
#endif
		    "using_cppnetlib_v2"
#ifdef _WIN32
		    ".exe"
#endif
		    );
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(application_build_dir / relative, arguments, application_build_dir,
		                                            output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit));
	}
}
<commit_msg>limit the build output for travis<commit_after>#include "log.hpp"
#include "boost_root.hpp"
#include "temporary.hpp"
#include "cdm_boost.hpp"
#include "cdm/cmake_generator.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <cdm/locate_cache.hpp>
#include <ventura/cmake.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/circular_buffer.hpp>

namespace
{
	ventura::absolute_path const this_file = *ventura::absolute_path::create(__FILE__);
	ventura::absolute_path const test = *ventura::parent(this_file);
	ventura::absolute_path const repository = *ventura::parent(test);
}

BOOST_AUTO_TEST_CASE(test_using_cppnetlib_v2)
{
	cdm::travis_keep_alive_printer keep_travis_alive;
	ventura::absolute_path const app_source = repository / "application/using_cppnetlib_v2";
	ventura::absolute_path const app_cdm_source = app_source / "cdm";
	ventura::absolute_path const tmp = cdm::get_temporary_root_for_testing() / "cdm";
	ventura::absolute_path const module_temporaries = tmp / "mod";
	ventura::absolute_path const application_build_dir = tmp / "using_cppnetlib_v2";
	ventura::recreate_directories(module_temporaries, Si::throw_);
	ventura::recreate_directories(application_build_dir, Si::throw_);
	std::unique_ptr<std::ofstream> log_file = cdm::open_log(application_build_dir / "test_using_cppnetlib_v2.txt");
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(*log_file));
	ventura::absolute_path const build_configure = module_temporaries / "build_configure";
	ventura::recreate_directories(build_configure, Si::throw_);
	{
		std::vector<Si::noexcept_string> arguments;
		{
			ventura::absolute_path const include = repository / "dependencies/silicium";
			arguments.emplace_back("-DSILICIUM_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		{
			ventura::absolute_path const include = repository / "dependencies/ventura";
			arguments.emplace_back("-DVENTURA_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		Si::optional<ventura::absolute_path> const boost_root = cdm::get_boost_root_for_testing();
		if (boost_root)
		{
			cdm::generate_cmake_definitions_for_using_boost(Si::make_container_sink(arguments), *boost_root);
#if CDM_TESTS_RUNNING_ON_APPVEYOR
			arguments.emplace_back("-DBOOST_LIBRARYDIR=" + ventura::to_utf8_string(*boost_root / "lib32-msvc-14.0"));
#endif
		}
		ventura::absolute_path const modules = repository / "modules";
		arguments.emplace_back("-DCDM_CONFIGURE_INCLUDE_DIRS=" + ventura::to_utf8_string(modules) + ";" +
		                       ventura::to_utf8_string(repository));
		arguments.emplace_back(ventura::to_utf8_string(app_cdm_source));
		cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		Si::noexcept_string generated_cmake_arguments;
		{
			std::vector<Si::noexcept_string> arguments;
			ventura::relative_path const relative(
#ifdef _WIN32
			    "Debug/"
#endif
			    "configure"
#ifdef _WIN32
			    ".exe"
#endif
			    );
			auto configure_sink =
			    Si::Sink<char, Si::success>::erase(Si::make_container_sink(generated_cmake_arguments));
			ventura::process_parameters parameters;
			parameters.executable = build_configure / relative;
			parameters.arguments = ventura::arguments_to_os_strings(arguments);
			parameters.current_path = build_configure;
			boost::circular_buffer<char> console_output(0xffff);
			auto console_output_sink = Si::Sink<char, Si::success>::erase(Si::make_container_sink(console_output));
			parameters.err = &console_output_sink;
			parameters.out = &configure_sink;
			BOOST_REQUIRE_EQUAL(0, ventura::run_process(parameters));
			boost::copy(console_output, std::ostreambuf_iterator<char>(std::cerr));
			BOOST_REQUIRE(!generated_cmake_arguments.empty());
		}

		{
			std::vector<Si::noexcept_string> arguments;
			boost::algorithm::split(arguments, generated_cmake_arguments, [](char c)
			                        {
				                        return c >= 0 && c <= ' ';
				                    });
			BOOST_REQUIRE(!arguments.empty());
			BOOST_REQUIRE(arguments.back().empty());
			arguments.pop_back();
			cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
			BOOST_REQUIRE_EQUAL(0,
			                    ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
			                                         std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
			                                         ventura::environment_inheritance::inherit).get());
		}
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::os_string> arguments;
		ventura::relative_path const relative(
#ifdef _WIN32
		    "Debug/"
#endif
		    "using_cppnetlib_v2"
#ifdef _WIN32
		    ".exe"
#endif
		    );
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(application_build_dir / relative, arguments, application_build_dir,
		                                            output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit));
	}
}
<|endoftext|>


<commit_before>#pragma once
#include "error.hpp"

namespace frea {
	template <class T>
	struct Range {
		using value_t = T;
		value_t	from,
				to;

		constexpr static bool ExCmp = noexcept(value_t()>value_t(),
											value_t()==value_t()),
								ExEq = noexcept(from=to,
												from+=to),
								is_integral = std::is_integral<T>{};
		Range() = default;
		template <class T2>
		constexpr Range(const Range<T2>& r) noexcept(ExEq):
			Range(static_cast<T>(r.from), static_cast<T>(r.to)) {}
		constexpr Range(const value_t& f, const value_t& t) noexcept(ExEq):
			from(f),
			to(t)
		{
			D_Expect(from <= to, "invalid range");
		}
		//! 値の範囲チェック
		bool hit(const value_t& v) const noexcept(ExCmp) {
			return v >= from
				&& v <= to;
		}
		//! 範囲が重なっているか
		bool hit(const Range& r) const noexcept(ExCmp) {
			return !(to < r.from
					&& from > r.to);
		}
		bool operator == (const Range& r) const noexcept(ExCmp) {
			return from == r.from
				&& to == r.to;
		}
		bool operator != (const Range& r) const noexcept(ExCmp) {
			return !(this->operator == (r));
		}
		#define DEF_OP(op) \
			Range& operator op##= (const value_t& t) noexcept(ExEq) { \
				from op##= t; \
				to op##= t; \
				return *this; \
			} \
			Range operator op (const value_t& t) const noexcept(ExEq) { \
				return Range(from op t, to op t); \
			}
		DEF_OP(+)
		DEF_OP(-)
		DEF_OP(*)
		DEF_OP(/)
		#undef DEF_OP
	};
	using RangeI = Range<int_fast32_t>;
	using RangeF = Range<float>;
}
<commit_msg>range: 単一値での範囲指定<commit_after>#pragma once
#include "error.hpp"

namespace frea {
	template <class T>
	struct Range {
		using value_t = T;
		value_t	from,
				to;

		constexpr static bool ExCmp = noexcept(value_t()>value_t(),
											value_t()==value_t()),
								ExEq = noexcept(from=to,
												from+=to),
								is_integral = std::is_integral<T>{};
		Range() = default;
		template <class T2>
		constexpr Range(const Range<T2>& r) noexcept(ExEq):
			Range(static_cast<T>(r.from), static_cast<T>(r.to)) {}
		explicit constexpr Range(const value_t& f) noexcept(ExEq):
			Range(-f, f)
		{}
		constexpr Range(const value_t& f, const value_t& t) noexcept(ExEq):
			from(f),
			to(t)
		{
			D_Expect(from <= to, "invalid range");
		}
		//! 値の範囲チェック
		bool hit(const value_t& v) const noexcept(ExCmp) {
			return v >= from
				&& v <= to;
		}
		//! 範囲が重なっているか
		bool hit(const Range& r) const noexcept(ExCmp) {
			return !(to < r.from
					&& from > r.to);
		}
		bool operator == (const Range& r) const noexcept(ExCmp) {
			return from == r.from
				&& to == r.to;
		}
		bool operator != (const Range& r) const noexcept(ExCmp) {
			return !(this->operator == (r));
		}
		#define DEF_OP(op) \
			Range& operator op##= (const value_t& t) noexcept(ExEq) { \
				from op##= t; \
				to op##= t; \
				return *this; \
			} \
			Range operator op (const value_t& t) const noexcept(ExEq) { \
				return Range(from op t, to op t); \
			}
		DEF_OP(+)
		DEF_OP(-)
		DEF_OP(*)
		DEF_OP(/)
		#undef DEF_OP
	};
	using RangeI = Range<int_fast32_t>;
	using RangeF = Range<float>;
}
<|endoftext|>


<commit_before>#include "log.hpp"
#include "boost_root.hpp"
#include "temporary.hpp"
#include "cdm_boost.hpp"
#include "cdm/cmake_generator.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <cdm/locate_cache.hpp>
#include <ventura/cmake.hpp>
#include <boost/algorithm/string/split.hpp>

namespace
{
	ventura::absolute_path const this_file = *ventura::absolute_path::create(__FILE__);
	ventura::absolute_path const test = *ventura::parent(this_file);
	ventura::absolute_path const repository = *ventura::parent(test);
}

BOOST_AUTO_TEST_CASE(test_using_cppnetlib_v2)
{
	cdm::travis_keep_alive_printer keep_travis_alive;
	ventura::absolute_path const app_source = repository / "application/using_cppnetlib_v2";
	ventura::absolute_path const app_cdm_source = app_source / "cdm";
	ventura::absolute_path const tmp = cdm::get_temporary_root_for_testing() / "cdm";
	ventura::absolute_path const module_temporaries = tmp / "mod";
	ventura::absolute_path const application_build_dir = tmp / "using_cppnetlib_v2";
	ventura::recreate_directories(module_temporaries, Si::throw_);
	ventura::recreate_directories(application_build_dir, Si::throw_);
	std::unique_ptr<std::ofstream> log_file = cdm::open_log(application_build_dir / "test_using_cppnetlib_v2.txt");
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(*log_file));
	ventura::absolute_path const build_configure = module_temporaries / "build_configure";
	ventura::recreate_directories(build_configure, Si::throw_);
	{
		std::vector<Si::noexcept_string> arguments;
		{
			ventura::absolute_path const include = repository / "dependencies/silicium";
			arguments.emplace_back("-DSILICIUM_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		{
			ventura::absolute_path const include = repository / "dependencies/ventura";
			arguments.emplace_back("-DVENTURA_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		Si::optional<ventura::absolute_path> const boost_root = cdm::get_boost_root_for_testing();
		if (boost_root)
		{
			cdm::generate_cmake_definitions_for_using_boost(Si::make_container_sink(arguments), *boost_root);
#if CDM_TESTS_RUNNING_ON_APPVEYOR
			arguments.emplace_back("-DBOOST_LIBRARYDIR=" + ventura::to_utf8_string(*boost_root / "lib32-msvc-14.0"));
#endif
		}
		ventura::absolute_path const modules = repository / "modules";
		arguments.emplace_back("-DCDM_CONFIGURE_INCLUDE_DIRS=" + ventura::to_utf8_string(modules) + ";" +
		                       ventura::to_utf8_string(repository));
		arguments.emplace_back(ventura::to_utf8_string(app_cdm_source));
		cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		Si::noexcept_string generated_cmake_arguments;
		{
			std::vector<Si::noexcept_string> arguments;
			ventura::relative_path const relative(
#ifdef _WIN32
			    "Debug/"
#endif
			    "configure"
#ifdef _WIN32
			    ".exe"
#endif
			    );
			auto configure_sink =
			    Si::Sink<char, Si::success>::erase(Si::make_container_sink(generated_cmake_arguments));
			ventura::process_parameters parameters;
			parameters.executable = build_configure / relative;
			parameters.arguments = ventura::arguments_to_os_strings(arguments);
			parameters.current_path = build_configure;
			auto console_output = Si::Sink<char, Si::success>::erase(Si::ostream_ref_sink(std::cerr));
			parameters.err = &console_output;
			parameters.out = &configure_sink;
			BOOST_REQUIRE_EQUAL(0, ventura::run_process(parameters));
			BOOST_REQUIRE(!generated_cmake_arguments.empty());
		}

		{
			std::vector<Si::noexcept_string> arguments;
			boost::algorithm::split(arguments, generated_cmake_arguments, [](char c)
			                        {
				                        return c >= 0 && c <= ' ';
				                    });
			BOOST_REQUIRE(!arguments.empty());
			BOOST_REQUIRE(arguments.back().empty());
			arguments.pop_back();
			cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
			BOOST_REQUIRE_EQUAL(0,
			                    ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
			                                         std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
			                                         ventura::environment_inheritance::inherit).get());
		}
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::os_string> arguments;
		ventura::relative_path const relative(
#ifdef _WIN32
		    "Debug/"
#endif
		    "using_cppnetlib_v2"
#ifdef _WIN32
		    ".exe"
#endif
		    );
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(application_build_dir / relative, arguments, application_build_dir,
		                                            output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit));
	}
}
<commit_msg>limit the console output for travis<commit_after>#include "log.hpp"
#include "boost_root.hpp"
#include "temporary.hpp"
#include "cdm_boost.hpp"
#include "cdm/cmake_generator.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <cdm/locate_cache.hpp>
#include <ventura/cmake.hpp>
#include <boost/algorithm/string/split.hpp>

namespace
{
	ventura::absolute_path const this_file = *ventura::absolute_path::create(__FILE__);
	ventura::absolute_path const test = *ventura::parent(this_file);
	ventura::absolute_path const repository = *ventura::parent(test);
}

BOOST_AUTO_TEST_CASE(test_using_cppnetlib_v2)
{
	cdm::travis_keep_alive_printer keep_travis_alive;
	ventura::absolute_path const app_source = repository / "application/using_cppnetlib_v2";
	ventura::absolute_path const app_cdm_source = app_source / "cdm";
	ventura::absolute_path const tmp = cdm::get_temporary_root_for_testing() / "cdm";
	ventura::absolute_path const module_temporaries = tmp / "mod";
	ventura::absolute_path const application_build_dir = tmp / "using_cppnetlib_v2";
	ventura::recreate_directories(module_temporaries, Si::throw_);
	ventura::recreate_directories(application_build_dir, Si::throw_);
	std::unique_ptr<std::ofstream> log_file = cdm::open_log(application_build_dir / "test_using_cppnetlib_v2.txt");
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(*log_file));
	ventura::absolute_path const build_configure = module_temporaries / "build_configure";
	ventura::recreate_directories(build_configure, Si::throw_);
	{
		std::vector<Si::noexcept_string> arguments;
		{
			ventura::absolute_path const include = repository / "dependencies/silicium";
			arguments.emplace_back("-DSILICIUM_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		{
			ventura::absolute_path const include = repository / "dependencies/ventura";
			arguments.emplace_back("-DVENTURA_INCLUDE_DIR=" + ventura::to_utf8_string(include));
		}
		Si::optional<ventura::absolute_path> const boost_root = cdm::get_boost_root_for_testing();
		if (boost_root)
		{
			cdm::generate_cmake_definitions_for_using_boost(Si::make_container_sink(arguments), *boost_root);
#if CDM_TESTS_RUNNING_ON_APPVEYOR
			arguments.emplace_back("-DBOOST_LIBRARYDIR=" + ventura::to_utf8_string(*boost_root / "lib32-msvc-14.0"));
#endif
		}
		ventura::absolute_path const modules = repository / "modules";
		arguments.emplace_back("-DCDM_CONFIGURE_INCLUDE_DIRS=" + ventura::to_utf8_string(modules) + ";" +
		                       ventura::to_utf8_string(repository));
		arguments.emplace_back(ventura::to_utf8_string(app_cdm_source));
		cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, build_configure, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		Si::noexcept_string generated_cmake_arguments;
		{
			std::vector<Si::noexcept_string> arguments;
			ventura::relative_path const relative(
#ifdef _WIN32
			    "Debug/"
#endif
			    "configure"
#ifdef _WIN32
			    ".exe"
#endif
			    );
			auto configure_sink =
			    Si::Sink<char, Si::success>::erase(Si::make_container_sink(generated_cmake_arguments));
			ventura::process_parameters parameters;
			parameters.executable = build_configure / relative;
			parameters.arguments = ventura::arguments_to_os_strings(arguments);
			parameters.current_path = build_configure;
			auto console_output = cdm::make_program_output_printer(Si::ostream_ref_sink(std::cerr));
			parameters.err = &console_output;
			parameters.out = &configure_sink;
			BOOST_REQUIRE_EQUAL(0, ventura::run_process(parameters));
			BOOST_REQUIRE(!generated_cmake_arguments.empty());
		}

		{
			std::vector<Si::noexcept_string> arguments;
			boost::algorithm::split(arguments, generated_cmake_arguments, [](char c)
			                        {
				                        return c >= 0 && c <= ' ';
				                    });
			BOOST_REQUIRE(!arguments.empty());
			BOOST_REQUIRE(arguments.back().empty());
			arguments.pop_back();
			cdm::generate_default_cmake_generator_arguments(Si::make_container_sink(arguments));
			BOOST_REQUIRE_EQUAL(0,
			                    ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
			                                         std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
			                                         ventura::environment_inheritance::inherit).get());
		}
	}

	{
		std::vector<Si::noexcept_string> arguments;
		arguments.emplace_back("--build");
		arguments.emplace_back(".");
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(ventura::cmake_exe, arguments, application_build_dir, output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit).get());
	}

	{
		std::vector<Si::os_string> arguments;
		ventura::relative_path const relative(
#ifdef _WIN32
		    "Debug/"
#endif
		    "using_cppnetlib_v2"
#ifdef _WIN32
		    ".exe"
#endif
		    );
		BOOST_REQUIRE_EQUAL(0, ventura::run_process(application_build_dir / relative, arguments, application_build_dir,
		                                            output,
		                                            std::vector<std::pair<Si::os_char const *, Si::os_char const *>>(),
		                                            ventura::environment_inheritance::inherit));
	}
}
<|endoftext|>