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

#define HEADER_INFO_SIZE 68

// Based on a true story by the Nederlands Kanker Instituut (AVS_HEIMANN.CPP
// from the 20090608)

// Includes
#include <fstream>
#include "rtkHisImageIO.h"
#include "rtkMacro.h"

//--------------------------------------------------------------------
// Read Image Information
void rtk::HisImageIO::ReadImageInformation()
{
  // open file
  std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);

  if ( file.fail() )
    itkGenericExceptionMacro(<< "Could not open file (for reading): "
                             << m_FileName);

  // read header
  char header[HEADER_INFO_SIZE];
  file.read(header, HEADER_INFO_SIZE);

  if (header[0]!=0 || header[1]!=112 || header[2]!=68 || header[3]!=0) {
    itkExceptionMacro(<< "rtk::HisImageIO::ReadImageInformation: file "
                      << m_FileName
                      << " not in Heimann HIS format version 100");
    return;
    }

  int nrframes, type, ulx, uly, brx, bry;
  m_HeaderSize  = header[10] + (header[11]<<8);
  ulx           = header[12] + (header[13]<<8);
  uly           = header[14] + (header[15]<<8);
  brx           = header[16] + (header[17]<<8);
  bry           = header[18] + (header[19]<<8);
  nrframes      = header[20] + (header[21]<<8);
  type          = header[32] + (header[34]<<8);

  switch(type)
    {
    case  4:
      SetComponentType(itk::ImageIOBase::USHORT);
      break;
//    case  8: SetComponentType(itk::ImageIOBase::INT);   break;
//    case 16: SetComponentType(itk::ImageIOBase::FLOAT); break;
//    case 32: SetComponentType(itk::ImageIOBase::INT);   break;
    default:
      SetComponentType(itk::ImageIOBase::USHORT);
      break;
    }

  switch(nrframes)
    {
    case 1:
      SetNumberOfDimensions(2);
      break;
    default:
      SetNumberOfDimensions(3);
      break;
    }

  SetDimensions(0, bry-uly+1);
  SetDimensions(1, brx-ulx+1);
  if (nrframes>1)
    SetDimensions(2, nrframes);

  SetSpacing(0, 409.6/GetDimensions(0) );
  SetSpacing(1, 409.6/GetDimensions(1) );

  SetOrigin(0, -0.5*(GetDimensions(0)-1)*GetSpacing(0) );
  SetOrigin(1, -0.5*(GetDimensions(1)-1)*GetSpacing(1) );
} ////

//--------------------------------------------------------------------
// Read Image Information
bool rtk::HisImageIO::CanReadFile(const char* FileNameToRead)
{
  std::string                  filename(FileNameToRead);
  const std::string::size_type it = filename.find_last_of( "." );
  std::string                  fileExt( filename, it+1, filename.length() );

  if (fileExt != std::string("his") )
    return false;
  return true;
} ////

//--------------------------------------------------------------------
// Read Image Content
void rtk::HisImageIO::Read(void * buffer)
{
  // open file
  std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);

  if ( file.fail() )
    itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);

  file.seekg(m_HeaderSize+HEADER_INFO_SIZE, std::ios::beg);
  if ( file.fail() )
    itkExceptionMacro(<<"File seek failed (His Read)");

  file.read( (char*)buffer, GetImageSizeInBytes() );
  if ( file.fail() )
    itkExceptionMacro(<<"Read failed: Wanted "
                      << GetImageSizeInBytes()
                      << " bytes, but read "
                      << file.gcount() << " bytes. The current state is: "
                      << file.rdstate() );
}

//--------------------------------------------------------------------
bool rtk::HisImageIO::CanWriteFile( const char* itkNotUsed(FileNameToWrite) )
{
  return false;
}

//--------------------------------------------------------------------
// Write Image
void rtk::HisImageIO::Write( const void* itkNotUsed(buffer) )
{
} ////
<commit_msg>Update rtkHisImageIO.cxx<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#define HEADER_INFO_SIZE 68

// Based on a true story by the Nederlands Kanker Instituut (AVS_HEIMANN.CPP
// from the 20090608)

// Includes
#include <fstream>
#include "rtkHisImageIO.h"
#include "rtkMacro.h"

//--------------------------------------------------------------------
// Read Image Information
void rtk::HisImageIO::ReadImageInformation()
{
  // open file
  std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);

  if ( file.fail() )
    itkGenericExceptionMacro(<< "Could not open file (for reading): "
                             << m_FileName);

  // read header
  unsigned char header[HEADER_INFO_SIZE];
  file.read((char*)header, HEADER_INFO_SIZE);

  if (header[0]!=0 || header[1]!=112 || header[2]!=68 || header[3]!=0) {
    itkExceptionMacro(<< "rtk::HisImageIO::ReadImageInformation: file "
                      << m_FileName
                      << " not in Heimann HIS format version 100");
    return;
    }

  int nrframes, type, ulx, uly, brx, bry;
  m_HeaderSize  = header[10] + (header[11]<<8);
  ulx           = header[12] + (header[13]<<8);
  uly           = header[14] + (header[15]<<8);
  brx           = header[16] + (header[17]<<8);
  bry           = header[18] + (header[19]<<8);
  nrframes      = header[20] + (header[21]<<8);
  type          = header[32] + (header[34]<<8);

  switch(type)
    {
    case  4:
      SetComponentType(itk::ImageIOBase::USHORT);
      break;
//    case  8: SetComponentType(itk::ImageIOBase::INT);   break;
//    case 16: SetComponentType(itk::ImageIOBase::FLOAT); break;
//    case 32: SetComponentType(itk::ImageIOBase::INT);   break;
    default:
      SetComponentType(itk::ImageIOBase::USHORT);
      break;
    }

  switch(nrframes)
    {
    case 1:
      SetNumberOfDimensions(2);
      break;
    default:
      SetNumberOfDimensions(3);
      break;
    }

  SetDimensions(0, bry-uly+1);
  SetDimensions(1, brx-ulx+1);
  if (nrframes>1)
    SetDimensions(2, nrframes);

  SetSpacing(0, 409.6/GetDimensions(0) );
  SetSpacing(1, 409.6/GetDimensions(1) );

  SetOrigin(0, -0.5*(GetDimensions(0)-1)*GetSpacing(0) );
  SetOrigin(1, -0.5*(GetDimensions(1)-1)*GetSpacing(1) );
} ////

//--------------------------------------------------------------------
// Read Image Information
bool rtk::HisImageIO::CanReadFile(const char* FileNameToRead)
{
  std::string                  filename(FileNameToRead);
  const std::string::size_type it = filename.find_last_of( "." );
  std::string                  fileExt( filename, it+1, filename.length() );

  if (fileExt != std::string("his") )
    return false;
  return true;
} ////

//--------------------------------------------------------------------
// Read Image Content
void rtk::HisImageIO::Read(void * buffer)
{
  // open file
  std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);

  if ( file.fail() )
    itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);

  file.seekg(m_HeaderSize+HEADER_INFO_SIZE, std::ios::beg);
  if ( file.fail() )
    itkExceptionMacro(<<"File seek failed (His Read)");

  file.read( (char*)buffer, GetImageSizeInBytes() );
  if ( file.fail() )
    itkExceptionMacro(<<"Read failed: Wanted "
                      << GetImageSizeInBytes()
                      << " bytes, but read "
                      << file.gcount() << " bytes. The current state is: "
                      << file.rdstate() );
}

//--------------------------------------------------------------------
bool rtk::HisImageIO::CanWriteFile( const char* itkNotUsed(FileNameToWrite) )
{
  return false;
}

//--------------------------------------------------------------------
// Write Image
void rtk::HisImageIO::Write( const void* itkNotUsed(buffer) )
{
} ////
<|endoftext|>


<commit_before>/* -*-C-*-
###############################################################################
#
# File:         oldlist.cpp
# Description:  List processing procedures.
# Author:       Mark Seaman, Software Productivity
#
# (c) Copyright 1987, Hewlett-Packard Company.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
#
###############################################################################

  This file contains a set of general purpose list manipulation routines.
  These routines can be used in a wide variety of ways to provide several
  different popular data structures. A new list can be created by declaring
  a variable of type 'LIST', and can be initialized with the value 'NIL_LIST'.
  All of these routines check for the NIL_LIST condition before dereferencing
  pointers.  NOTE:  There is a users' manual available in printed form from
  Mark Seaman at (303) 350-4492 at Greeley Hard Copy.

  To implement a STACK use:

  push         to add to the Stack             l = push(l, (LIST)"jim");
  pop          to remove items from the Stack  l = pop(l);
  first_node   to access the head              name = (char *)first_node(l);

  To implement a QUEUE use:

  push_last    to add to the Queue              l = push_last(l, (LIST)"x");
  pop          remove items from the Queue      l = pop(l);
  first_node   to access the head               name = (char *)first_node (l);

  To implement LISP like functions use:

  first_node   CAR                              x = (int)first_node(l);
  rest         CDR                              l = list_rest (l);
  push         CONS                             l = push(l, (LIST)this);
  last         LAST                             x = last(l);
  concat       APPEND                           l = concat(r, s);
  count        LENGTH                           x = count(l);
  search       MEMBER                           if (search(l, x, nullptr))

  The following rules of closure exist for the functions provided.
  a = first_node (push (a, b))
  b = list_rest (push (a, b))
  a = push (pop (a), a))        For all a <> NIL_LIST
  a = reverse (reverse (a))

******************************************************************************/
#include "oldlist.h"
#include <cstdio>
#include <cstring>      // for strcmp
#include "errcode.h"    // for ASSERT_HOST
#include "structures.h"

/*----------------------------------------------------------------------
              M a c r o s
----------------------------------------------------------------------*/
#define add_on(l, x) l = push(l, first_node(x))
#define next_one(l) l = list_rest(l)

/**********************************************************************
 *  c o p y   f i r s t
 *
 *  Do the appropriate kind a push operation to copy the first node from
 *  one list to another.
 *
 **********************************************************************/

#define copy_first(l1,l2)  \
(l2=push(l2, first_node(l1)))

/*----------------------------------------------------------------------
              F u n c t i o n s
----------------------------------------------------------------------*/

/**********************************************************************
 *  i s   s a m e
 *
 *  Compare the list node with the key value return TRUE (non-zero)
 *  if they are equivalent strings.  (Return FALSE if not)
 **********************************************************************/
static int is_same(void *item1, void *item2) {
  return strcmp((char *)item1, (char *)item2) == 0;
}

/**********************************************************************
 *  c o u n t
 *
 *  Recursively count the elements in  a list.  Return the count.
 **********************************************************************/
int count(LIST var_list) {
  int temp = 0;

  iterate(var_list) temp += 1;
  return (temp);
}

/**********************************************************************
 *  d e l e t e    d
 *
 *  Delete all the elements out of the current list that match the key.
 *  This operation destroys the original list.  The caller will supply a
 *  routine that will compare each node to the
 *  key, and return a non-zero value when they match.
 **********************************************************************/
LIST delete_d(LIST list, void *key, int_compare is_equal) {
  LIST result = NIL_LIST;
  LIST last_one = NIL_LIST;

  if (is_equal == nullptr) is_equal = is_same;

  while (list != NIL_LIST) {
    if (!(*is_equal)(first_node(list), key)) {
      if (last_one == NIL_LIST) {
        last_one = list;
        list = list_rest(list);
        result = last_one;
        set_rest(last_one, NIL_LIST);
      } else {
        set_rest(last_one, list);
        last_one = list;
        list = list_rest(list);
        set_rest(last_one, NIL_LIST);
      }
    } else {
      list = pop(list);
    }
  }
  return (result);
}

/**********************************************************************
 *  d e s t r o y
 *
 *  Return the space taken by a list to the heap.
 **********************************************************************/
LIST destroy(LIST list) {
  LIST next;

  while (list != NIL_LIST) {
    next = list_rest(list);
    free_cell(list);
    list = next;
  }
  return (NIL_LIST);
}

/**********************************************************************
 *  d e s t r o y   n o d e s
 *
 *  Return the space taken by the LISTs of a list to the heap.
 **********************************************************************/
void destroy_nodes(LIST list, void_dest destructor) {
  ASSERT_HOST(destructor != nullptr);

  while (list != NIL_LIST) {
    if (first_node(list) != nullptr) (*destructor)(first_node(list));
    list = pop(list);
  }
}

/**********************************************************************
 *  l a s t
 *
 *  Return the last list item (this is list type).
 **********************************************************************/
LIST last(LIST var_list) {
  while (list_rest(var_list) != NIL_LIST) var_list = list_rest(var_list);
  return (var_list);
}

/**********************************************************************
 *  p o p
 *
 *  Return the list with the first element removed.  Destroy the space
 *  that it occupied in the list.
 **********************************************************************/
LIST pop(LIST list) {
  LIST temp;

  temp = list_rest(list);

  if (list != NIL_LIST) {
    free_cell(list);
  }
  return (temp);
}

/**********************************************************************
 *  p u s h
 *
 *  Create a list element.  Push the second parameter (the node) onto
 *  the first parameter (the list). Return the new list to the caller.
 **********************************************************************/
LIST push(LIST list, void *element) {
  LIST t;

  t = new_cell();
  t->node = (LIST)element;
  set_rest(t, list);
  return (t);
}

/**********************************************************************
 *  p u s h   l a s t
 *
 *  Create a list element. Add the element onto the end of the list.
 **********************************************************************/
LIST push_last(LIST list, void *item) {
  LIST t;

  if (list != NIL_LIST) {
    t = last(list);
    t->next = push(NIL_LIST, item);
    return (list);
  } else
    return (push(NIL_LIST, item));
}

/**********************************************************************
 *   s e a r c h
 *
 *  Search list, return NIL_LIST if not found. Return the list starting from
 *  the item if found.  The compare routine "is_equal" is passed in as
 *  the third parameter to this routine.
 **********************************************************************/
LIST search(LIST list, void *key, int_compare is_equal) {
  if (is_equal == nullptr) is_equal = is_same;

  iterate(list) if ((*is_equal)(first_node(list), key)) return (list);
  return (NIL_LIST);
}
<commit_msg>cutil: Replace TRUE, FALSE by true, false<commit_after>/* -*-C-*-
###############################################################################
#
# File:         oldlist.cpp
# Description:  List processing procedures.
# Author:       Mark Seaman, Software Productivity
#
# (c) Copyright 1987, Hewlett-Packard Company.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
#
###############################################################################

  This file contains a set of general purpose list manipulation routines.
  These routines can be used in a wide variety of ways to provide several
  different popular data structures. A new list can be created by declaring
  a variable of type 'LIST', and can be initialized with the value 'NIL_LIST'.
  All of these routines check for the NIL_LIST condition before dereferencing
  pointers.  NOTE:  There is a users' manual available in printed form from
  Mark Seaman at (303) 350-4492 at Greeley Hard Copy.

  To implement a STACK use:

  push         to add to the Stack             l = push(l, (LIST)"jim");
  pop          to remove items from the Stack  l = pop(l);
  first_node   to access the head              name = (char *)first_node(l);

  To implement a QUEUE use:

  push_last    to add to the Queue              l = push_last(l, (LIST)"x");
  pop          remove items from the Queue      l = pop(l);
  first_node   to access the head               name = (char *)first_node (l);

  To implement LISP like functions use:

  first_node   CAR                              x = (int)first_node(l);
  rest         CDR                              l = list_rest (l);
  push         CONS                             l = push(l, (LIST)this);
  last         LAST                             x = last(l);
  concat       APPEND                           l = concat(r, s);
  count        LENGTH                           x = count(l);
  search       MEMBER                           if (search(l, x, nullptr))

  The following rules of closure exist for the functions provided.
  a = first_node (push (a, b))
  b = list_rest (push (a, b))
  a = push (pop (a), a))        For all a <> NIL_LIST
  a = reverse (reverse (a))

******************************************************************************/
#include "oldlist.h"
#include <cstdio>
#include <cstring>      // for strcmp
#include "errcode.h"    // for ASSERT_HOST
#include "structures.h"

/*----------------------------------------------------------------------
              M a c r o s
----------------------------------------------------------------------*/
#define add_on(l, x) l = push(l, first_node(x))
#define next_one(l) l = list_rest(l)

/**********************************************************************
 *  c o p y   f i r s t
 *
 *  Do the appropriate kind a push operation to copy the first node from
 *  one list to another.
 *
 **********************************************************************/

#define copy_first(l1,l2)  \
(l2=push(l2, first_node(l1)))

/*----------------------------------------------------------------------
              F u n c t i o n s
----------------------------------------------------------------------*/

/**********************************************************************
 *  i s   s a m e
 *
 *  Compare the list node with the key value return true (non-zero)
 *  if they are equivalent strings.  (Return false if not)
 **********************************************************************/
static int is_same(void *item1, void *item2) {
  return strcmp((char *)item1, (char *)item2) == 0;
}

/**********************************************************************
 *  c o u n t
 *
 *  Recursively count the elements in  a list.  Return the count.
 **********************************************************************/
int count(LIST var_list) {
  int temp = 0;

  iterate(var_list) temp += 1;
  return (temp);
}

/**********************************************************************
 *  d e l e t e    d
 *
 *  Delete all the elements out of the current list that match the key.
 *  This operation destroys the original list.  The caller will supply a
 *  routine that will compare each node to the
 *  key, and return a non-zero value when they match.
 **********************************************************************/
LIST delete_d(LIST list, void *key, int_compare is_equal) {
  LIST result = NIL_LIST;
  LIST last_one = NIL_LIST;

  if (is_equal == nullptr) is_equal = is_same;

  while (list != NIL_LIST) {
    if (!(*is_equal)(first_node(list), key)) {
      if (last_one == NIL_LIST) {
        last_one = list;
        list = list_rest(list);
        result = last_one;
        set_rest(last_one, NIL_LIST);
      } else {
        set_rest(last_one, list);
        last_one = list;
        list = list_rest(list);
        set_rest(last_one, NIL_LIST);
      }
    } else {
      list = pop(list);
    }
  }
  return (result);
}

/**********************************************************************
 *  d e s t r o y
 *
 *  Return the space taken by a list to the heap.
 **********************************************************************/
LIST destroy(LIST list) {
  LIST next;

  while (list != NIL_LIST) {
    next = list_rest(list);
    free_cell(list);
    list = next;
  }
  return (NIL_LIST);
}

/**********************************************************************
 *  d e s t r o y   n o d e s
 *
 *  Return the space taken by the LISTs of a list to the heap.
 **********************************************************************/
void destroy_nodes(LIST list, void_dest destructor) {
  ASSERT_HOST(destructor != nullptr);

  while (list != NIL_LIST) {
    if (first_node(list) != nullptr) (*destructor)(first_node(list));
    list = pop(list);
  }
}

/**********************************************************************
 *  l a s t
 *
 *  Return the last list item (this is list type).
 **********************************************************************/
LIST last(LIST var_list) {
  while (list_rest(var_list) != NIL_LIST) var_list = list_rest(var_list);
  return (var_list);
}

/**********************************************************************
 *  p o p
 *
 *  Return the list with the first element removed.  Destroy the space
 *  that it occupied in the list.
 **********************************************************************/
LIST pop(LIST list) {
  LIST temp;

  temp = list_rest(list);

  if (list != NIL_LIST) {
    free_cell(list);
  }
  return (temp);
}

/**********************************************************************
 *  p u s h
 *
 *  Create a list element.  Push the second parameter (the node) onto
 *  the first parameter (the list). Return the new list to the caller.
 **********************************************************************/
LIST push(LIST list, void *element) {
  LIST t;

  t = new_cell();
  t->node = (LIST)element;
  set_rest(t, list);
  return (t);
}

/**********************************************************************
 *  p u s h   l a s t
 *
 *  Create a list element. Add the element onto the end of the list.
 **********************************************************************/
LIST push_last(LIST list, void *item) {
  LIST t;

  if (list != NIL_LIST) {
    t = last(list);
    t->next = push(NIL_LIST, item);
    return (list);
  } else
    return (push(NIL_LIST, item));
}

/**********************************************************************
 *   s e a r c h
 *
 *  Search list, return NIL_LIST if not found. Return the list starting from
 *  the item if found.  The compare routine "is_equal" is passed in as
 *  the third parameter to this routine.
 **********************************************************************/
LIST search(LIST list, void *key, int_compare is_equal) {
  if (is_equal == nullptr) is_equal = is_same;

  iterate(list) if ((*is_equal)(first_node(list), key)) return (list);
  return (NIL_LIST);
}
<|endoftext|>


<commit_before>#ifndef _w32_mt_Thread_hpp__
#define _w32_mt_Thread_hpp__

// Copyright (c) 2009-2012, Andre Caron (andre.l.caron@gmail.com)
// 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.
//
// 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
// HOLDER 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.

#include "__configure__.hpp"
#include <w32/types.hpp>
#include <w32/Timespan.hpp>
#include <w32/Waitable.hpp>

namespace w32 { namespace mt {

    /*!
     * @ingroup w32-mt
     * @brief Entity within a process that can be scheduled for execution.
     *
     * All threads of a process share its virtual address space and system
     * resources. In addition, each thread maintains exception handlers, a
     * scheduling priority, thread local storage, a unique thread
     * identifier, and a set of structures the system will use to save the
     * thread context until it is scheduled. The thread context includes
     * the thread's set of machine registers, the kernel stack, a thread
     * environment block, and a user stack in the address space of the
     * thread's process.
     *
     * Threads can also have their own security context, which can be used
     * for impersonating clients.
     */
    class Thread :
        public Object
    {
        /* nested types. */
    public:
        class Priority;

            /*!
             * @brief Integer value uniquely identifying a running thread.
             *
             * If you need to identify a thread through inter-process
             * communication, sending this value is more convenient than sending
             * the handle (which is not valid in the other process).
             */
        typedef dword Identifier;

            /*!
             * @brief Value returned by a thread to indicate status.
             */
        typedef dword Status;

            /*!
             * @brief Value that may be passed to induce context in the thread.
             * @see Function
             */
        typedef pointer Parameter;

            /*!
             * @brief Required function signature.
             * @see Parameter
             * @see Status
             * @see function
             * @see method
             */
        typedef Status(__stdcall*Function)(Parameter);

        template<dword(*)(void*)> struct function;
        template<typename T, dword(T::*)()> struct method;

        /* class methods. */
    public:
        static Thread current ();
        static Thread open ( Identifier identifier );

    private:
        static ::HANDLE allocate
            ( ::LPTHREAD_START_ROUTINE function, ::LPVOID context );

        /* construction. */
    public:
        explicit Thread ( const Handle& handle );
        explicit Thread ( Function function, Parameter parameter = 0 );

        template<dword(*F)(void*)>
        Thread ( function<F> function, void * context=0 )
            : Object(allocate(function, context))
        {
        }

        template<typename T, dword(T::*M)()>
        Thread ( T& object, method<T,M> method )
            : Object(allocate(method, &object))
        {
        }

        /* methods. */
    public:
            /*!
             * @brief Obtains the thread identifier.
             *
             * @return Theead identifier.
             * @see ExistingThread
             */
        Identifier identifier () const;

            /*!
             * @brief Obtains the thread' priority level.
             * @return The thread's priority.
             */
        Priority priority () const;

            /*!
             * @brief Changes the thread' priority level.
             * @param priority The thread's new priority level.
             */
        void priority ( const Priority& priority );

            /*!
             * @brief Suspends the target thread's execution (if running).
             *
             * @return Thread suspend count. If this 1, you have just
             *   pre-empted the thread and prevented it from being re-scheduled
             *   for execution.
             *
             * @warning This function is primarily destined for debuggers. In
             *   particular, it is not intended for thread synchronization
             *   . Suspending a thread that owns a synchronization resource
             *   is risking deadlock, @e even if that thread is well designed.
             */
        dword suspend ();

            /*!
             * @brief Attemps to wake up a thread that was @c suspend()ed.
             *
             * @note This function must be called if you created an initially
             *   suspended thread (useful trick for pre-allocating threads).
             *
             * @return Thread suspend count. When this is 0, the thread is no
             *   longer suspended and its execution is scheduled to resume.
             */
        dword resume ();

            /*!
             * @brief Kills the thread.
             *
             * This is a violent and brutal death and might cause chaos.
             *
             * @note Never use 259 as exit code because it is reserved. Using it
             *    may cause applications waiting on the process to run an
             *    infinite loop.
             *
             * @param status Exit code for the executing thread.
             */
        void terminate ( Status status = 0 );

            /*!
             * @brief Obtains the exit code for the thread.
             *
             * This status may have been set in a few different contexts: the
             * return value from the thread' entry point, the value set by the
             * thread when it called "ExitThread()", or the value set by the
             * caller to "TerminateThread()".
             *
             * Note that this function never blocks, even if the process is
             * still alive. If so, a special code (259) is returned.
             *
             * @note Because 259 may technically be returned by a misbehaved
             *    process, you should wait for the thread to complete and only
             *    then request the status code.
             *
             * @return Status, or 259 (still alive).
             */
        Status status () const;

            /*!
             * @brief Checks if the thread is still alive and kicking.
             *
             * This is documented to work correctly, even though it actually
             * doesn't ask the system if the thread is alive (there are no
             * means to do so).
             *
             * @note Because 259 may technically be returned by a misbehaved
             *    thread, you should wait for the thread to complete to make
             *    sure the thread actually terminated. The wait functions
             *    are better suited for this.
             *
             * @return True if the thread's status is not 259.
             */
        bool alive () const;

        void join () const;
        bool join ( const Timespan& timeout ) const;

        /* operators. */
    public:
        operator Waitable () const;
    };

    // compile-time binding of free function to callback function.
    template<dword(*F)(void*)>
    struct Thread::function
    {
        operator ::LPTHREAD_START_ROUTINE () const
        {
            return (&entry_point);
        }

    private:
        static ::DWORD __stdcall entry_point ( ::LPVOID context )
        {
            return (F(context));
        }
    };

    template<typename T, dword(T::*M)()>
    struct Thread::method
    {
        operator ::LPTHREAD_START_ROUTINE () const
        {
            return (&entry_point);
        }

    private:
        static ::DWORD __stdcall entry_point ( ::LPVOID context )
        {
            return ((static_cast<T*>(context)->*M)());
        }
    };

        /*!
         * @brief Requests pause of execution for a fixed duration of time.
         *
         * The system cannot guarantee waking up \i exactly after the specified
         * amount of time. Make sure longer suspension is safe for your
         * application.
         */
    void sleep ( const Timespan& timespan );
    bool alertable ( const Timespan& timespan );

    class Sleep
    {
        w32::Timespan myTimespan;
    public:
        explicit Sleep ( const w32::Timespan& timespan )
            : myTimespan(timespan)
        {}

        void operator() () const
        {
            mt::sleep(myTimespan);
        }
    };

        /*!
         * @brief Hint to the scheduler for assining processor cycles.
         */
    class Thread::Priority
    {
        /* nested types. */
    public:
        typedef int Value;

        /* class data. */
    public:
        static const Priority idle ();
        static const Priority lowest ();
        static const Priority lower ();
        static const Priority normal ();
        static const Priority higher ();
        static const Priority highest ();
        static const Priority critical ();

        /* data. */
    private:
        Value myValue;

        /* construction. */
    private:
        Priority ( Value value );

        /* methods. */
    public:
        Value value () const;

        /* operators. */
    public:
        operator Value () const;
    };

        /*!
         * @brief Prematurily ends the current thread's time slice.
         *
         * This mechanism is normally used for politeness: when executing a
         * potentially heavy task, the system may attribute extra processor
         * time for your thread. When that is the case, the system as a whole
         * may become less responsive. Use this to keep giving the illusion
         * of simultaneous execution.
         */
    void yield ();

        /*!
         * @brief Prematurily ends the current thread.
         *
         * The preferred means of ending a thread is returning from it's entry
         * point. In particular, this may cause resource leaks in your
         * application because C++ objects normally release resources in their
         * destructor and the stack is not unwound.
         */
    void exit ( uint status );

} }

#endif /* _w32_mt_Thread_hpp__ */
<commit_msg>Prevent crash on thread object cleanup.<commit_after>#ifndef _w32_mt_Thread_hpp__
#define _w32_mt_Thread_hpp__

// Copyright (c) 2009-2012, Andre Caron (andre.l.caron@gmail.com)
// 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.
//
// 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
// HOLDER 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.

#include "__configure__.hpp"
#include <w32/types.hpp>
#include <w32/Timespan.hpp>
#include <w32/Waitable.hpp>

namespace w32 { namespace mt {

    /*!
     * @ingroup w32-mt
     * @brief Entity within a process that can be scheduled for execution.
     *
     * All threads of a process share its virtual address space and system
     * resources. In addition, each thread maintains exception handlers, a
     * scheduling priority, thread local storage, a unique thread
     * identifier, and a set of structures the system will use to save the
     * thread context until it is scheduled. The thread context includes
     * the thread's set of machine registers, the kernel stack, a thread
     * environment block, and a user stack in the address space of the
     * thread's process.
     *
     * Threads can also have their own security context, which can be used
     * for impersonating clients.
     */
    class Thread :
        public Object
    {
        /* nested types. */
    public:
        class Priority;

            /*!
             * @brief Integer value uniquely identifying a running thread.
             *
             * If you need to identify a thread through inter-process
             * communication, sending this value is more convenient than sending
             * the handle (which is not valid in the other process).
             */
        typedef dword Identifier;

            /*!
             * @brief Value returned by a thread to indicate status.
             */
        typedef dword Status;

            /*!
             * @brief Value that may be passed to induce context in the thread.
             * @see Function
             */
        typedef pointer Parameter;

            /*!
             * @brief Required function signature.
             * @see Parameter
             * @see Status
             * @see function
             * @see method
             */
        typedef Status(__stdcall*Function)(Parameter);

        template<dword(*)(void*)> struct function;
        template<typename T, dword(T::*)()> struct method;

        /* class methods. */
    public:
        static Thread current ();
        static Thread open ( Identifier identifier );

    private:
        static ::HANDLE allocate
            ( ::LPTHREAD_START_ROUTINE function, ::LPVOID context );

        /* construction. */
    public:
        explicit Thread ( const Handle& handle );
        explicit Thread ( Function function, Parameter parameter = 0 );

        template<dword(*F)(void*)>
        Thread ( function<F> function, void * context=0 )
            : Object(claim(allocate(function, context)))
        {
        }

        template<typename T, dword(T::*M)()>
        Thread ( T& object, method<T,M> method )
            : Object(claim(allocate(method, &object)))
        {
        }

        /* methods. */
    public:
            /*!
             * @brief Obtains the thread identifier.
             *
             * @return Theead identifier.
             * @see ExistingThread
             */
        Identifier identifier () const;

            /*!
             * @brief Obtains the thread' priority level.
             * @return The thread's priority.
             */
        Priority priority () const;

            /*!
             * @brief Changes the thread' priority level.
             * @param priority The thread's new priority level.
             */
        void priority ( const Priority& priority );

            /*!
             * @brief Suspends the target thread's execution (if running).
             *
             * @return Thread suspend count. If this 1, you have just
             *   pre-empted the thread and prevented it from being re-scheduled
             *   for execution.
             *
             * @warning This function is primarily destined for debuggers. In
             *   particular, it is not intended for thread synchronization
             *   . Suspending a thread that owns a synchronization resource
             *   is risking deadlock, @e even if that thread is well designed.
             */
        dword suspend ();

            /*!
             * @brief Attemps to wake up a thread that was @c suspend()ed.
             *
             * @note This function must be called if you created an initially
             *   suspended thread (useful trick for pre-allocating threads).
             *
             * @return Thread suspend count. When this is 0, the thread is no
             *   longer suspended and its execution is scheduled to resume.
             */
        dword resume ();

            /*!
             * @brief Kills the thread.
             *
             * This is a violent and brutal death and might cause chaos.
             *
             * @note Never use 259 as exit code because it is reserved. Using it
             *    may cause applications waiting on the process to run an
             *    infinite loop.
             *
             * @param status Exit code for the executing thread.
             */
        void terminate ( Status status = 0 );

            /*!
             * @brief Obtains the exit code for the thread.
             *
             * This status may have been set in a few different contexts: the
             * return value from the thread' entry point, the value set by the
             * thread when it called "ExitThread()", or the value set by the
             * caller to "TerminateThread()".
             *
             * Note that this function never blocks, even if the process is
             * still alive. If so, a special code (259) is returned.
             *
             * @note Because 259 may technically be returned by a misbehaved
             *    process, you should wait for the thread to complete and only
             *    then request the status code.
             *
             * @return Status, or 259 (still alive).
             */
        Status status () const;

            /*!
             * @brief Checks if the thread is still alive and kicking.
             *
             * This is documented to work correctly, even though it actually
             * doesn't ask the system if the thread is alive (there are no
             * means to do so).
             *
             * @note Because 259 may technically be returned by a misbehaved
             *    thread, you should wait for the thread to complete to make
             *    sure the thread actually terminated. The wait functions
             *    are better suited for this.
             *
             * @return True if the thread's status is not 259.
             */
        bool alive () const;

        void join () const;
        bool join ( const Timespan& timeout ) const;

        /* operators. */
    public:
        operator Waitable () const;
    };

    // compile-time binding of free function to callback function.
    template<dword(*F)(void*)>
    struct Thread::function
    {
        operator ::LPTHREAD_START_ROUTINE () const
        {
            return (&entry_point);
        }

    private:
        static ::DWORD __stdcall entry_point ( ::LPVOID context )
        {
            return (F(context));
        }
    };

    template<typename T, dword(T::*M)()>
    struct Thread::method
    {
        operator ::LPTHREAD_START_ROUTINE () const
        {
            return (&entry_point);
        }

    private:
        static ::DWORD __stdcall entry_point ( ::LPVOID context )
        {
            return ((static_cast<T*>(context)->*M)());
        }
    };

        /*!
         * @brief Requests pause of execution for a fixed duration of time.
         *
         * The system cannot guarantee waking up \i exactly after the specified
         * amount of time. Make sure longer suspension is safe for your
         * application.
         */
    void sleep ( const Timespan& timespan );
    bool alertable ( const Timespan& timespan );

    class Sleep
    {
        w32::Timespan myTimespan;
    public:
        explicit Sleep ( const w32::Timespan& timespan )
            : myTimespan(timespan)
        {}

        void operator() () const
        {
            mt::sleep(myTimespan);
        }
    };

        /*!
         * @brief Hint to the scheduler for assining processor cycles.
         */
    class Thread::Priority
    {
        /* nested types. */
    public:
        typedef int Value;

        /* class data. */
    public:
        static const Priority idle ();
        static const Priority lowest ();
        static const Priority lower ();
        static const Priority normal ();
        static const Priority higher ();
        static const Priority highest ();
        static const Priority critical ();

        /* data. */
    private:
        Value myValue;

        /* construction. */
    private:
        Priority ( Value value );

        /* methods. */
    public:
        Value value () const;

        /* operators. */
    public:
        operator Value () const;
    };

        /*!
         * @brief Prematurily ends the current thread's time slice.
         *
         * This mechanism is normally used for politeness: when executing a
         * potentially heavy task, the system may attribute extra processor
         * time for your thread. When that is the case, the system as a whole
         * may become less responsive. Use this to keep giving the illusion
         * of simultaneous execution.
         */
    void yield ();

        /*!
         * @brief Prematurily ends the current thread.
         *
         * The preferred means of ending a thread is returning from it's entry
         * point. In particular, this may cause resource leaks in your
         * application because C++ objects normally release resources in their
         * destructor and the stack is not unwound.
         */
    void exit ( uint status );

} }

#endif /* _w32_mt_Thread_hpp__ */
<|endoftext|>


<commit_before>#ifndef ANY_HPP
# define ANY_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <stdexcept>

#include <typeinfo>

#include <type_traits>

#include <utility>

namespace generic
{

class any
{
public:
  template <typename T>
  using remove_cvr = ::std::remove_cv<
    typename ::std::remove_reference<T>::type
  >;

  using typeid_t = ::std::uintptr_t;

  template <typename T>
  static typeid_t type_id() noexcept
  {
    static char const c{};

    return typeid_t(&c);
  }

  any() = default;

  any(any const& other) :
    content(other.content ? other.content->cloner_(other.content) : nullptr)
  {
  }

  any(any&& other) noexcept { *this = ::std::move(other); }

  template<typename ValueType,
    typename = typename ::std::enable_if<
      !::std::is_same<
        any, typename ::std::decay<ValueType>::type
      >{}
    >::type
  >
  any(ValueType&& value) :
    content(new holder<typename remove_cvr<ValueType>::type>(
      ::std::forward<ValueType>(value)))
  {
  }

  ~any() { delete content; }

public: // modifiers
  void clear() { swap(any()); }

  bool empty() const noexcept { return !*this; }

  void swap(any& other) noexcept { ::std::swap(content, other.content); }

  void swap(any&& other) noexcept { ::std::swap(content, other.content); }

  any& operator=(any const& rhs)
  {
    return content == rhs.content ? *this : *this = any(rhs);
  }

  any& operator=(any&& rhs) noexcept { swap(rhs); return *this; }

  template<typename ValueType,
    typename = typename ::std::enable_if<
      !::std::is_same<
        any, typename ::std::decay<ValueType>::type
      >{}
    >::type
  >
  any& operator=(ValueType&& rhs)
  {
    return *this = any(::std::forward<ValueType>(rhs));
  }

public: // queries

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

  typeid_t type_id() const noexcept
  {
    return *this ? content->type_id_ : typeid_t(nullptr);
  }

  auto type() const noexcept -> decltype(type_id()) { return type_id(); }

public: // get

private: // types

  template <typename T>
  static constexpr T* begin(T& value) noexcept
  {
    return &value;
  }

  template <typename T, ::std::size_t N>
  static constexpr typename ::std::remove_all_extents<T>::type*
  begin(T (&array)[N]) noexcept
  {
    return begin(*array);
  }

  template <typename T>
  static constexpr T* end(T& value) noexcept
  {
    return &value + 1;
  }

  template <typename T, ::std::size_t N>
  static constexpr typename ::std::remove_all_extents<T>::type*
  end(T (&array)[N]) noexcept
  {
    return end(array[N - 1]);
  }

  struct placeholder
  {
    typeid_t const type_id_;

    placeholder* (* const cloner_)(placeholder*);

    virtual ~placeholder() = default;

  protected:

    placeholder(typeid_t const ti, decltype(cloner_) const c) noexcept :
      type_id_(ti),
      cloner_(c)
    {
    }
  };

  template <typename ValueType>
  struct holder : public placeholder
  {
  public: // constructor
    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        !::std::is_array<U>{} &&
        !::std::is_copy_constructible<U>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), throwing_cloner),
      held(::std::forward<T>(value))
    {
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        !::std::is_array<U>{} &&
        ::std::is_copy_constructible<U>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), cloner),
      held(::std::forward<T>(value))
    {
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        ::std::is_array<U>{} &&
        ::std::is_move_assignable<
          typename ::std::remove_const<
            typename ::std::remove_all_extents<U>::type
          >::type
        >{} &&
        ::std::is_rvalue_reference<T&&>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), throwing_cloner)
    {
      ::std::copy(::std::make_move_iterator(begin(value)),
        ::std::make_move_iterator(end(value)),
        begin(held));
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        ::std::is_array<U>{} &&
        ::std::is_copy_assignable<
          typename ::std::remove_const<
            typename ::std::remove_all_extents<U>::type
          >::type
        >{} &&
        !::std::is_rvalue_reference<T&&>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), cloner)
    {
      ::std::copy(begin(value), end(value), begin(held));
    }

    holder& operator=(holder const&) = delete;

    static placeholder* cloner(placeholder* const base)
    {
      return new holder<ValueType>(static_cast<holder*>(base)->held);
    }

    static placeholder* throwing_cloner(placeholder* const)
    {
      throw ::std::logic_error("");
    }

  public:
    typename ::std::remove_const<ValueType>::type held;
  };

private: // representation

  template<typename ValueType>
  friend ValueType* any_cast(any*) noexcept;

  template<typename ValueType>
  friend ValueType* unsafe_any_cast(any*) noexcept;

#ifdef NDEBUG
  template <typename U> friend U& get(any&) noexcept;
  template <typename U> friend U const& get(any const&) noexcept;
#else
  template <typename U> friend U& get(any&);
  template <typename U> friend U const& get(any const&);
#endif // NDEBUG

  placeholder* content{};
};

template<typename ValueType>
inline ValueType* unsafe_any_cast(any* const operand) noexcept
{
  return &static_cast<any::holder<ValueType>*>(operand->content)->held;
}

template<typename ValueType>
inline ValueType const* unsafe_any_cast(any const* const operand) noexcept
{
  return unsafe_any_cast<ValueType>(const_cast<any*>(operand));
}

template<typename ValueType>
inline ValueType* any_cast(any* const operand) noexcept
{
  return operand &&
    (operand->type_id() ==
      any::type_id<typename any::remove_cvr<ValueType>::type>()) ?
    &static_cast<any::holder<ValueType>*>(operand->content)->held :
    nullptr;
}

template<typename ValueType>
inline ValueType const* any_cast(any const* const operand) noexcept
{
  return any_cast<ValueType>(const_cast<any*>(operand));
}

template<typename ValueType>
inline ValueType any_cast(any& operand)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename any::remove_cvr<ValueType>::type;

#ifndef NDEBUG
  auto const result(any_cast<nonref>(&operand));

  if (result)
  {
    return *result;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return *unsafe_any_cast<nonref>(&operand);
#endif // NDEBUG
}

template<typename ValueType>
inline ValueType any_cast(any const& operand) noexcept(
  noexcept(
    any_cast<typename any::remove_cvr<ValueType>::type>(
      const_cast<any&>(operand)
    )
  )
)
{
  using nonref = typename any::remove_cvr<ValueType>::type;

  return any_cast<nonref const&>(const_cast<any&>(operand));
}

template <typename U>
U& get(any& a)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename ::generic::any::remove_cvr<U>::type;

#ifndef NDEBUG
  if (a.content && (a.type_id() == a.type_id<nonref>()))
  {
    return static_cast<any::holder<nonref>*>(a.content)->held;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return static_cast<any::holder<nonref>*>(a.content)->held;
#endif // NDEBUG
}

template <typename U>
U const& get(any const& a)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename ::generic::any::remove_cvr<U>::type;

#ifndef NDEBUG
  if (a.content && (a.type_id() == a.type_id<nonref>()))
  {
    return static_cast<any::holder<nonref const>*>(a.content)->held;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return static_cast<any::holder<nonref>*>(a.content)->held;
#endif // NDEBUG
}

template <typename U>
typename ::std::enable_if<
  !(::std::is_enum<U>{} || ::std::is_fundamental<U>{}),
  U const&
>::type
cget(any const& a) noexcept(
  noexcept(get<U const&>(::std::declval<any const>())))
{
  return get<U const&>(a);
}

template <typename U>
typename ::std::enable_if<
  ::std::is_enum<U>{} || ::std::is_fundamental<U>{},
  U
>::type
cget(any const& a) noexcept(
  noexcept(get<U>(::std::declval<any const>())))
{
  return get<U>();
}

}

#endif // ANY_HPP
<commit_msg>some fixes<commit_after>#ifndef ANY_HPP
# define ANY_HPP
# pragma once

#include <cassert>

#include <cstdint>

#include <stdexcept>

#include <typeinfo>

#include <type_traits>

#include <utility>

namespace generic
{

class any
{
public:
  template <typename T>
  using remove_cvr = ::std::remove_cv<
    typename ::std::remove_reference<T>::type
  >;

  using typeid_t = ::std::uintptr_t;

  template <typename T>
  static typeid_t type_id() noexcept
  {
    static char const c{};

    return typeid_t(&c);
  }

  any() = default;

  any(any const& other) :
    content(other.content ? other.content->cloner_(other.content) : nullptr)
  {
  }

  any(any&& other) noexcept { *this = ::std::move(other); }

  template<typename ValueType,
    typename = typename ::std::enable_if<
      !::std::is_same<
        any, typename ::std::decay<ValueType>::type
      >{}
    >::type
  >
  any(ValueType&& value) :
    content(new holder<typename remove_cvr<ValueType>::type>(
      ::std::forward<ValueType>(value)))
  {
  }

  ~any() { delete content; }

public: // modifiers
  void clear() { swap(any()); }

  bool empty() const noexcept { return !*this; }

  void swap(any& other) noexcept { ::std::swap(content, other.content); }

  void swap(any&& other) noexcept { ::std::swap(content, other.content); }

  any& operator=(any const& rhs)
  {
    return content == rhs.content ? *this : *this = any(rhs);

    return *this;
  }

  any& operator=(any&& rhs) noexcept { swap(rhs); return *this; }

  template<typename ValueType,
    typename = typename ::std::enable_if<
      !::std::is_same<
        any, typename ::std::decay<ValueType>::type
      >{}
    >::type
  >
  any& operator=(ValueType&& rhs)
  {
    return *this = any(::std::forward<ValueType>(rhs));
  }

public: // queries

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

  typeid_t type_id() const noexcept
  {
    return *this ? content->type_id_ : typeid_t(nullptr);
  }

  auto type() const noexcept -> decltype(type_id()) { return type_id(); }

public: // get

private: // types

  template <typename T>
  static constexpr T* begin(T& value) noexcept
  {
    return &value;
  }

  template <typename T, ::std::size_t N>
  static constexpr typename ::std::remove_all_extents<T>::type*
  begin(T (&array)[N]) noexcept
  {
    return begin(*array);
  }

  template <typename T>
  static constexpr T* end(T& value) noexcept
  {
    return &value + 1;
  }

  template <typename T, ::std::size_t N>
  static constexpr typename ::std::remove_all_extents<T>::type*
  end(T (&array)[N]) noexcept
  {
    return end(array[N - 1]);
  }

  struct placeholder
  {
    typeid_t const type_id_;

    placeholder* (* const cloner_)(placeholder*);

    virtual ~placeholder() = default;

  protected:

    placeholder(typeid_t const ti, decltype(cloner_) const c) noexcept :
      type_id_(ti),
      cloner_(c)
    {
    }
  };

  template <typename ValueType>
  struct holder : public placeholder
  {
  public: // constructor
    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        !::std::is_array<U>{} &&
        !::std::is_copy_constructible<U>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), throwing_cloner),
      held(::std::forward<T>(value))
    {
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        !::std::is_array<U>{} &&
        ::std::is_copy_constructible<U>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), cloner),
      held(::std::forward<T>(value))
    {
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        ::std::is_array<U>{} &&
        ::std::is_move_assignable<
          typename ::std::remove_const<
            typename ::std::remove_all_extents<U>::type
          >::type
        >{} &&
        ::std::is_rvalue_reference<T&&>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), throwing_cloner)
    {
      ::std::copy(::std::make_move_iterator(begin(value)),
        ::std::make_move_iterator(end(value)),
        begin(held));
    }

    template <class T, typename U = ValueType>
    holder(T&& value,
      typename ::std::enable_if<
        ::std::is_array<U>{} &&
        ::std::is_copy_assignable<
          typename ::std::remove_const<
            typename ::std::remove_all_extents<U>::type
          >::type
        >{} &&
        !::std::is_rvalue_reference<T&&>{}
      >::type* = nullptr) :
      placeholder(type_id<ValueType>(), cloner)
    {
      ::std::copy(begin(value), end(value), begin(held));
    }

    holder& operator=(holder const&) = delete;

    static placeholder* cloner(placeholder* const base)
    {
      return new holder<ValueType>(static_cast<holder*>(base)->held);
    }

    static placeholder* throwing_cloner(placeholder* const)
    {
      throw ::std::logic_error("");
    }

  public:
    typename ::std::remove_const<ValueType>::type held;
  };

private: // representation

  template<typename ValueType>
  friend ValueType* any_cast(any*) noexcept;

  template<typename ValueType>
  friend ValueType* unsafe_any_cast(any*) noexcept;

#ifdef NDEBUG
  template <typename U> friend U& get(any&) noexcept;
  template <typename U> friend U const& get(any const&) noexcept;
#else
  template <typename U> friend U& get(any&);
  template <typename U> friend U const& get(any const&);
#endif // NDEBUG

  placeholder* content{};
};

template<typename ValueType>
inline ValueType* unsafe_any_cast(any* const operand) noexcept
{
  return &static_cast<any::holder<ValueType>*>(operand->content)->held;
}

template<typename ValueType>
inline ValueType const* unsafe_any_cast(any const* const operand) noexcept
{
  return unsafe_any_cast<ValueType>(const_cast<any*>(operand));
}

template<typename ValueType>
inline ValueType* any_cast(any* const operand) noexcept
{
  return operand &&
    (operand->type_id() ==
      any::type_id<typename any::remove_cvr<ValueType>::type>()) ?
    &static_cast<any::holder<ValueType>*>(operand->content)->held :
    nullptr;
}

template<typename ValueType>
inline ValueType const* any_cast(any const* const operand) noexcept
{
  return any_cast<ValueType>(const_cast<any*>(operand));
}

template<typename ValueType>
inline ValueType any_cast(any& operand)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename any::remove_cvr<ValueType>::type;

#ifndef NDEBUG
  auto const result(any_cast<nonref>(&operand));

  if (result)
  {
    return *result;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return *unsafe_any_cast<nonref>(&operand);
#endif // NDEBUG
}

template<typename ValueType>
inline ValueType any_cast(any const& operand) noexcept(
  noexcept(
    any_cast<typename any::remove_cvr<ValueType>::type>(
      const_cast<any&>(operand)
    )
  )
)
{
  using nonref = typename any::remove_cvr<ValueType>::type;

  return any_cast<nonref const&>(const_cast<any&>(operand));
}

template <typename U>
U& get(any& a)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename ::generic::any::remove_cvr<U>::type;

#ifndef NDEBUG
  if (a.content && (a.type_id() == a.type_id<nonref>()))
  {
    return static_cast<any::holder<nonref>*>(a.content)->held;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return static_cast<any::holder<nonref>*>(a.content)->held;
#endif // NDEBUG
}

template <typename U>
U const& get(any const& a)
#ifdef NDEBUG
  noexcept
#endif
{
  using nonref = typename ::generic::any::remove_cvr<U>::type;

#ifndef NDEBUG
  if (a.content && (a.type_id() == a.type_id<nonref>()))
  {
    return static_cast<any::holder<nonref const>*>(a.content)->held;
  }
  else
  {
    throw ::std::bad_cast();
  }
#else
  return static_cast<any::holder<nonref>*>(a.content)->held;
#endif // NDEBUG
}

template <typename U>
typename ::std::enable_if<
  !(::std::is_enum<U>{} || ::std::is_fundamental<U>{}),
  U const&
>::type
cget(any const& a) noexcept(
  noexcept(get<U const&>(::std::declval<any const>())))
{
  return get<U const&>(a);
}

template <typename U>
typename ::std::enable_if<
  ::std::is_enum<U>{} || ::std::is_fundamental<U>{},
  U
>::type
cget(any const& a) noexcept(
  noexcept(get<U>(::std::declval<any const>())))
{
  return get<U>();
}

}

#endif // ANY_HPP
<|endoftext|>


<commit_before>/*************************************************************************/
/*  resource_saver_png.cpp                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "resource_saver_png.h"

#include "core/image.h"
#include "core/os/file_access.h"
#include "drivers/png/png_driver_common.h"
#include "scene/resources/texture.h"

Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {

	Ref<ImageTexture> texture = p_resource;

	ERR_FAIL_COND_V(!texture.is_valid(), ERR_INVALID_PARAMETER);
	ERR_EXPLAIN("Can't save empty texture as PNG");
	ERR_FAIL_COND_V(!texture->get_width() || !texture->get_height(), ERR_INVALID_PARAMETER);

	Ref<Image> img = texture->get_data();

	Error err = save_image(p_path, img);

	return err;
};

Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img) {

	PoolVector<uint8_t> buffer;
	Error err = PNGDriverCommon::image_to_png(p_img, buffer);
	ERR_FAIL_COND_V(err, err);
	FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
	ERR_FAIL_COND_V(err, err);

	PoolVector<uint8_t>::Read reader = buffer.read();

	file->store_buffer(reader.ptr(), buffer.size());
	if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
		memdelete(file);
		return ERR_CANT_CREATE;
	}

	file->close();
	memdelete(file);

	return OK;
}

bool ResourceSaverPNG::recognize(const RES &p_resource) const {

	return (p_resource.is_valid() && p_resource->is_class("ImageTexture"));
}

void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {

	if (Object::cast_to<Texture>(*p_resource)) {
		p_extensions->push_back("png");
	}
}

ResourceSaverPNG::ResourceSaverPNG() {

	Image::save_png_func = &save_image;
};
<commit_msg>Fix CurveTexture being listed as saveable to .png<commit_after>/*************************************************************************/
/*  resource_saver_png.cpp                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "resource_saver_png.h"

#include "core/image.h"
#include "core/os/file_access.h"
#include "drivers/png/png_driver_common.h"
#include "scene/resources/texture.h"

Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {

	Ref<ImageTexture> texture = p_resource;

	ERR_FAIL_COND_V(!texture.is_valid(), ERR_INVALID_PARAMETER);
	ERR_EXPLAIN("Can't save empty texture as PNG");
	ERR_FAIL_COND_V(!texture->get_width() || !texture->get_height(), ERR_INVALID_PARAMETER);

	Ref<Image> img = texture->get_data();

	Error err = save_image(p_path, img);

	return err;
};

Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img) {

	PoolVector<uint8_t> buffer;
	Error err = PNGDriverCommon::image_to_png(p_img, buffer);
	ERR_FAIL_COND_V(err, err);
	FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
	ERR_FAIL_COND_V(err, err);

	PoolVector<uint8_t>::Read reader = buffer.read();

	file->store_buffer(reader.ptr(), buffer.size());
	if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
		memdelete(file);
		return ERR_CANT_CREATE;
	}

	file->close();
	memdelete(file);

	return OK;
}

bool ResourceSaverPNG::recognize(const RES &p_resource) const {

	return (p_resource.is_valid() && p_resource->is_class("ImageTexture"));
}

void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {

	if (Object::cast_to<ImageTexture>(*p_resource)) {
		p_extensions->push_back("png");
	}
}

ResourceSaverPNG::ResourceSaverPNG() {

	Image::save_png_func = &save_image;
};
<|endoftext|>


<commit_before>// Copyright (c) 2009 Roman Neuhauser
// Distributed under the MIT license (see LICENSE file)
// vim: sw=4 sts=4 et fdm=marker cms=\ //\ %s

#ifndef INIPHILE_INCLUDE_AST_HPP
#define INIPHILE_INCLUDE_AST_HPP

#include <vector>
#include <stack>
#include <map>
#include <string>

#include <boost/foreach.hpp>
#include <boost/variant.hpp>
#include <boost/fusion/include/map.hpp>

#include "metagram.hpp"
#include "manip.hpp"

namespace iniphile
{
namespace ast
{

struct leaf
{ // {{{
    metagram::optval value;
}; // }}}

struct branch;

typedef boost::variant<
    boost::recursive_wrapper<branch>
  , leaf
> node;

struct branch
{ // {{{
    typedef std::map<std::string, node> type;
    type children;
}; // }}}

} // namespace ast

typedef std::stack<ast::branch *> astack;

void
push_path(valpath const & path, astack & stk) // {{{
{
    auto current = stk.top();
    BOOST_FOREACH (auto label, path) {
        current->children[label] = ast::branch();
        current = &boost::get<ast::branch>(current->children[label]);
        stk.push(current);
    }
} // }}}
void
pop_path(valpath const & path, astack & stk) // {{{
{
    BOOST_FOREACH (auto label, path) {
        stk.pop();
    }
} // }}}
valpath
dirname(valpath const & path) // {{{
{
    auto rv(path);
    rv.pop_back();
    return rv;
} // }}}
std::string
basename(valpath const & path) // {{{
{
    return path.back();
} // }}}
void
add_sym(metagram::optname name, metagram::optval val, ast::branch & scope) // {{{
{
    ast::leaf v;
    v.value = val;
    scope.children[name] = v;
} // }}}

ast::node
normalize(metagram::config const & cst) // {{{
{
    astack stk;
    ast::branch root;
    stk.push(&root);
    BOOST_FOREACH (auto sec, cst) {
        auto secpath(to_valpath(sec.first));
        push_path(secpath, stk);

        BOOST_FOREACH (auto prop, sec.second) {
            auto proppath(to_valpath(prop.first));
            auto dir(dirname(proppath));
            auto name(basename(proppath));
            push_path(dir, stk);
            add_sym(name, prop.second, *stk.top());
            pop_path(dir, stk);
        }
        pop_path(secpath, stk);
    }
    return root;
} // }}}

template <class Iter>
class find_node
: public boost::static_visitor<ast::node>
// {{{
{
public:
    find_node(Iter pos, Iter end)
    : pos(pos)
    , end(end)
    {}
    ast::node operator()(ast::branch const & b) const
    {
        if (pos == end) {
            return ast::node();
        }
        auto p(pos);
        auto next(b.children.find(*p));
        if (next == b.children.end()) {
            return ast::node();
        }
        ++p;
        auto e(end);
        if (p == e) {
            return (*next).second;
        }
        return boost::apply_visitor(
            find_node<Iter>(p, e)
          , (*next).second
        );
    }
    ast::node operator()(ast::leaf const & l) const
    {
        return l;
    }
private:
    Iter pos;
    Iter end;
}; // }}}

std::string
get_string(ast::node const & cfg, valpath const & path) // {{{
{
    find_node<valpath::const_iterator> f(
        path.begin()
      , path.end()
    );
    auto rv = boost::apply_visitor(f, cfg);
    ast::leaf *l = boost::get<ast::leaf>(&rv);
    if (!l || l->value.empty()) {
        return "";
    }
    return l->value[0];
} // }}}

} // namespace iniphile::ast

#endif
<commit_msg>get_string(ast::node, std::string)<commit_after>// Copyright (c) 2009 Roman Neuhauser
// Distributed under the MIT license (see LICENSE file)
// vim: sw=4 sts=4 et fdm=marker cms=\ //\ %s

#ifndef INIPHILE_INCLUDE_AST_HPP
#define INIPHILE_INCLUDE_AST_HPP

#include <vector>
#include <stack>
#include <map>
#include <string>

#include <boost/foreach.hpp>
#include <boost/variant.hpp>
#include <boost/fusion/include/map.hpp>

#include "metagram.hpp"
#include "manip.hpp"

namespace iniphile
{
namespace ast
{

struct leaf
{ // {{{
    metagram::optval value;
}; // }}}

struct branch;

typedef boost::variant<
    boost::recursive_wrapper<branch>
  , leaf
> node;

struct branch
{ // {{{
    typedef std::map<std::string, node> type;
    type children;
}; // }}}

} // namespace ast

typedef std::stack<ast::branch *> astack;

void
push_path(valpath const & path, astack & stk) // {{{
{
    auto current = stk.top();
    BOOST_FOREACH (auto label, path) {
        current->children[label] = ast::branch();
        current = &boost::get<ast::branch>(current->children[label]);
        stk.push(current);
    }
} // }}}
void
pop_path(valpath const & path, astack & stk) // {{{
{
    BOOST_FOREACH (auto label, path) {
        stk.pop();
    }
} // }}}
valpath
dirname(valpath const & path) // {{{
{
    auto rv(path);
    rv.pop_back();
    return rv;
} // }}}
std::string
basename(valpath const & path) // {{{
{
    return path.back();
} // }}}
void
add_sym(metagram::optname name, metagram::optval val, ast::branch & scope) // {{{
{
    ast::leaf v;
    v.value = val;
    scope.children[name] = v;
} // }}}

ast::node
normalize(metagram::config const & cst) // {{{
{
    astack stk;
    ast::branch root;
    stk.push(&root);
    BOOST_FOREACH (auto sec, cst) {
        auto secpath(to_valpath(sec.first));
        push_path(secpath, stk);

        BOOST_FOREACH (auto prop, sec.second) {
            auto proppath(to_valpath(prop.first));
            auto dir(dirname(proppath));
            auto name(basename(proppath));
            push_path(dir, stk);
            add_sym(name, prop.second, *stk.top());
            pop_path(dir, stk);
        }
        pop_path(secpath, stk);
    }
    return root;
} // }}}

template <class Iter>
class find_node
: public boost::static_visitor<ast::node>
// {{{
{
public:
    find_node(Iter pos, Iter end)
    : pos(pos)
    , end(end)
    {}
    ast::node operator()(ast::branch const & b) const
    {
        if (pos == end) {
            return ast::node();
        }
        auto p(pos);
        auto next(b.children.find(*p));
        if (next == b.children.end()) {
            return ast::node();
        }
        ++p;
        auto e(end);
        if (p == e) {
            return (*next).second;
        }
        return boost::apply_visitor(
            find_node<Iter>(p, e)
          , (*next).second
        );
    }
    ast::node operator()(ast::leaf const & l) const
    {
        return l;
    }
private:
    Iter pos;
    Iter end;
}; // }}}

std::string
get_string(ast::node const & cfg, valpath const & path) // {{{
{
    find_node<valpath::const_iterator> f(
        path.begin()
      , path.end()
    );
    auto rv = boost::apply_visitor(f, cfg);
    ast::leaf *l = boost::get<ast::leaf>(&rv);
    if (!l || l->value.empty()) {
        return "";
    }
    return l->value[0];
} // }}}

std::string
get_string(ast::node const & cfg, std::string const & path) // {{{
{
    return get_string(cfg, to_valpath(path));
} // }}}

} // namespace iniphile::ast

#endif
<|endoftext|>


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

#ifndef _DTOBJFACTORY_HXX_
#define _DTOBJFACTORY_HXX_

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif

#include <systools/win32/comtools.hxx>

//------------------------------------------------------------------------
// deklarations
//------------------------------------------------------------------------

class CDTransObjFactory
{
public:
    virtual IDataObjectPtr SAL_CALL createDataObjFromTransferable( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager,
                                                                   const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& refXTransferable );
    virtual com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > SAL_CALL createTransferableFromDataObj(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager, IDataObjectPtr pIDataObject );
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.4.98); FILE MERGED 2008/04/01 15:13:31 thb 1.4.98.3: #i85898# Stripping all external header guards 2008/04/01 12:28:28 thb 1.4.98.2: #i85898# Stripping all external header guards 2008/03/31 13:08:55 rt 1.4.98.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: DtObjFactory.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _DTOBJFACTORY_HXX_
#define _DTOBJFACTORY_HXX_

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <cppuhelper/servicefactory.hxx>

#include <systools/win32/comtools.hxx>

//------------------------------------------------------------------------
// deklarations
//------------------------------------------------------------------------

class CDTransObjFactory
{
public:
    virtual IDataObjectPtr SAL_CALL createDataObjFromTransferable( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager,
                                                                   const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& refXTransferable );
    virtual com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > SAL_CALL createTransferableFromDataObj(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager, IDataObjectPtr pIDataObject );
};

#endif
<|endoftext|>