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

#include <string>
#include <list>
#include <windows.h>
#include <commctrl.h>

#include "app/gfx/native_theme_win.h"
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/resource_util.h"
#include "base/win_util.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"

TestShellPlatformDelegate::TestShellPlatformDelegate(
    const CommandLine& command_line)
    : command_line_(command_line) {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
}

TestShellPlatformDelegate::~TestShellPlatformDelegate() {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
}

void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
}

// This test approximates whether you are running the default themes for
// your platform by inspecting a couple of metrics.
// It does not catch all cases, but it does pick up on classic vs xp,
// and normal vs large fonts. Something it misses is changes to the color
// scheme (which will infact cause pixel test failures).
bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
  std::list<std::string> errors;

  OSVERSIONINFOEX osvi;
  ::ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  ::GetVersionEx((OSVERSIONINFO *)&osvi);

  // default to XP metrics, override if on Vista
  int requiredVScrollSize = 17;
  int requiredFontSize = -11; // 8 pt
  const WCHAR *requiredFont = L"Tahoma";
  bool isVista = false;
  if (osvi.dwMajorVersion == 6
      && osvi.dwMinorVersion == 0
      && osvi.wProductType == VER_NT_WORKSTATION) {
    requiredFont = L"Segoe UI";
    requiredFontSize = -12; // 9 pt
    isVista = true;
  } else if (osvi.dwMajorVersion == 5
             && osvi.dwMinorVersion == 1
             && osvi.wProductType == VER_NT_WORKSTATION) {
    // XP;
  } else {
    errors.push_back("Unsupported Operating System version "
                     "(must use XP or Vista).");
  }

  // on both XP and Vista, this metric will be 17 when font size is "Normal".
  // The size of drop-down menus depends on it.
  int vScrollSize = ::GetSystemMetrics(SM_CXVSCROLL);
  if (vScrollSize != requiredVScrollSize) {
    errors.push_back("Must use normal size fonts (96 dpi).");
  }

  // ClearType must be disabled, because the rendering is unpredictable.
  BOOL bFontSmoothing;
  SystemParametersInfo(SPI_GETFONTSMOOTHING, (UINT)0,
                       (PVOID)&bFontSmoothing, (UINT)0);
  int fontSmoothingType;
  SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, (UINT)0,
                       (PVOID)&fontSmoothingType, (UINT)0);
  if (bFontSmoothing && (fontSmoothingType == FE_FONTSMOOTHINGCLEARTYPE)) {
    errors.push_back("ClearType must be disabled.");
  }

  // Check that we're using the default system fonts
  NONCLIENTMETRICS metrics;
  win_util::GetNonClientMetrics(&metrics);
  LOGFONTW* system_fonts[] =
  { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };

  for (size_t i = 0; i < arraysize(system_fonts); ++i) {
    if (system_fonts[i]->lfHeight != requiredFontSize ||
        wcscmp(requiredFont, system_fonts[i]->lfFaceName)) {
      if (isVista)
        errors.push_back("Must use either the Aero or Basic theme.");
      else
        errors.push_back("Must use the default XP theme (Luna).");
      break;
    }
  }

  if (!errors.empty()) {
    fprintf(stderr, "%s",
      "##################################################################\n"
      "## Layout test system dependencies check failed.\n"
      "##\n");
    for (std::list<std::string>::iterator it = errors.begin();
         it != errors.end();
         ++it) {
      fprintf(stderr, "## %s\n", it->c_str());
    }
    fprintf(stderr, "%s",
      "##\n"
      "##################################################################\n");
  }
  return errors.empty();
}

void TestShellPlatformDelegate::SuppressErrorReporting() {
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
}

void TestShellPlatformDelegate::InitializeGUI() {
  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);
  TestShell::RegisterWindowClass();
}

void TestShellPlatformDelegate::SelectUnifiedTheme() {
  gfx::NativeTheme::instance()->DisableTheming();
}

void TestShellPlatformDelegate::SetWindowPositionForRecording(
    TestShell *shell) {
  // Move the window to the upper left corner for consistent
  // record/playback mode.  For automation, we want this to work
  // on build systems where the script invoking us is a background
  // process.  So for this case, make our window the topmost window
  // as well.
  ForegroundHelper::SetForeground(shell->mainWnd());
  ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
}
<commit_msg>Let layout tests run on Windows 7.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <list>
#include <windows.h>
#include <commctrl.h>

#include "app/gfx/native_theme_win.h"
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/resource_util.h"
#include "base/win_util.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"

TestShellPlatformDelegate::TestShellPlatformDelegate(
    const CommandLine& command_line)
    : command_line_(command_line) {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
}

TestShellPlatformDelegate::~TestShellPlatformDelegate() {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
}

void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
}

// This test approximates whether you are running the default themes for
// your platform by inspecting a couple of metrics.
// It does not catch all cases, but it does pick up on classic vs xp,
// and normal vs large fonts. Something it misses is changes to the color
// scheme (which will infact cause pixel test failures).
bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
  std::list<std::string> errors;

  OSVERSIONINFOEX osvi;
  ::ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  ::GetVersionEx((OSVERSIONINFO *)&osvi);

  // default to XP metrics, override if on Vista
  int requiredVScrollSize = 17;
  int requiredFontSize = -11; // 8 pt
  const wchar_t* requiredFont = L"Tahoma";
  // Consider Windows 7 as Vista.
  bool isVista = false;
  if (osvi.dwMajorVersion == 6
      && (osvi.dwMinorVersion == 0 || osvi.dwMinorVersion == 1)
      && osvi.wProductType == VER_NT_WORKSTATION) {
    requiredFont = L"Segoe UI";
    requiredFontSize = -12; // 9 pt
    isVista = true;
  } else if (osvi.dwMajorVersion == 5
             && osvi.dwMinorVersion == 1
             && osvi.wProductType == VER_NT_WORKSTATION) {
    // XP;
  } else {
    errors.push_back("Unsupported Operating System version "
                     "(must use XP or Vista).");
  }

  // on both XP and Vista, this metric will be 17 when font size is "Normal".
  // The size of drop-down menus depends on it.
  int vScrollSize = ::GetSystemMetrics(SM_CXVSCROLL);
  if (vScrollSize != requiredVScrollSize) {
    errors.push_back("Must use normal size fonts (96 dpi).");
  }

  // ClearType must be disabled, because the rendering is unpredictable.
  BOOL bFontSmoothing;
  SystemParametersInfo(SPI_GETFONTSMOOTHING, (UINT)0,
                       (PVOID)&bFontSmoothing, (UINT)0);
  int fontSmoothingType;
  SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, (UINT)0,
                       (PVOID)&fontSmoothingType, (UINT)0);
  if (bFontSmoothing && (fontSmoothingType == FE_FONTSMOOTHINGCLEARTYPE)) {
    errors.push_back("ClearType must be disabled.");
  }

  // Check that we're using the default system fonts
  NONCLIENTMETRICS metrics;
  win_util::GetNonClientMetrics(&metrics);
  LOGFONTW* system_fonts[] =
  { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };

  for (size_t i = 0; i < arraysize(system_fonts); ++i) {
    if (system_fonts[i]->lfHeight != requiredFontSize ||
        wcscmp(requiredFont, system_fonts[i]->lfFaceName)) {
      if (isVista)
        errors.push_back("Must use either the Aero or Basic theme.");
      else
        errors.push_back("Must use the default XP theme (Luna).");
      break;
    }
  }

  if (!errors.empty()) {
    fprintf(stderr, "%s",
      "##################################################################\n"
      "## Layout test system dependencies check failed.\n"
      "##\n");
    for (std::list<std::string>::iterator it = errors.begin();
         it != errors.end();
         ++it) {
      fprintf(stderr, "## %s\n", it->c_str());
    }
    fprintf(stderr, "%s",
      "##\n"
      "##################################################################\n");
  }
  return errors.empty();
}

void TestShellPlatformDelegate::SuppressErrorReporting() {
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
}

void TestShellPlatformDelegate::InitializeGUI() {
  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);
  TestShell::RegisterWindowClass();
}

void TestShellPlatformDelegate::SelectUnifiedTheme() {
  gfx::NativeTheme::instance()->DisableTheming();
}

void TestShellPlatformDelegate::SetWindowPositionForRecording(
    TestShell *shell) {
  // Move the window to the upper left corner for consistent
  // record/playback mode.  For automation, we want this to work
  // on build systems where the script invoking us is a background
  // process.  So for this case, make our window the topmost window
  // as well.
  ForegroundHelper::SetForeground(shell->mainWnd());
  ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.5  1999/12/17 01:28:53  rahulj
 * Merged in changes submitted for UnixWare 7 port. Platform
 * specific files are still missing.
 *
 * Revision 1.4  1999/12/16 23:47:10  rahulj
 * Updated for version 1.0.1
 *
 * Revision 1.3  1999/12/01 17:16:16  rahulj
 * Added support for IRIX 6.5.5 using SGI MIPSpro C++ 7.3 and 7.21 generating 32 bit objects. Changes submitted by Marc Stuessel
 *
 * Revision 1.2  1999/11/10 02:02:51  abagchi
 * Changed version numbers
 *
 * Revision 1.1.1.1  1999/11/09 01:05:35  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:45:19  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(XML4CDEFS_HPP)
#define XML4CDEFS_HPP

// ---------------------------------------------------------------------------
//  These are the various representations of the current version of XML4C.
//  These are updated for every build. They must be at the top because they
//  can be used by various per-compiler headers below.
// ---------------------------------------------------------------------------
#define XML4C_DLLVersionStr "1_0"
static const char* const    gXML4CVersionStr = "1_0";
static const char* const    gXML4CFullVersionStr = "1_0_1";
static const unsigned int   gXML4CMajVersion = 1;
static const unsigned int   gXML4CMinVersion = 0;
static const unsigned int   gXML4CRevision   = 1;

// ---------------------------------------------------------------------------
//  Include the header that does automatic sensing of the current platform
//  and compiler.
// ---------------------------------------------------------------------------
#include    <util/AutoSense.hpp>

// ---------------------------------------------------------------------------
//  According to the platform we include a platform specific file. This guy
//  will set up any platform specific stuff, such as character mode.
// ---------------------------------------------------------------------------
#if defined(XML_WIN32)
#include    <util/Platforms/Win32/Win32Defs.hpp>
#endif

#if defined(XML_AIX)
#include    <util/Platforms/AIX/AIXDefs.hpp>
#endif

#if defined(XML_SOLARIS)
#include    <util/Platforms/Solaris/SolarisDefs.hpp>
#endif

#if defined(XML_UNIXWARE)
#include    <util/Platforms/UnixWare/UnixWareDefs.hpp>
#endif

#if defined(XML_HPUX)
#include    <util/Platforms/HPUX/HPUXDefs.hpp>
#endif

#if defined(XML_IRIX)
#include    <util/Platforms/IRIX/IRIXDefs.hpp>
#endif

#if defined(XML_TANDEM)
#include    <util/Platforms/Tandem/TandemDefs.hpp>
#endif

#if defined(XML_LINUX)
#include    <util/Platforms/Linux/LinuxDefs.hpp>
#endif

#if defined(XML_OE390)
#include    <util/Platforms/OS390/OE390Defs.hpp>
#endif

#if defined(XML_OS2)
#include    <util/Platforms/OS2/OS2Defs.hpp>
#endif

#if defined(XML_MACOS)
#include	<util/Platforms/MaxOS/MacOSDefs.hpp>
#endif

// ---------------------------------------------------------------------------
//  And now we subinclude a header according to the development environment
//  we are on. This guy defines for each platform some basic stuff that is
//  specific to the development environment.
// ---------------------------------------------------------------------------
#if defined(XML_VISUALCPP)
#include    <util/Compilers/VCPPDefs.hpp>
#endif

#if defined(XML_CSET)
#include    <util/Compilers/CSetDefs.hpp>
#endif

#if defined(XML_BORLAND)
#include    <util/Compilers/BorlandCDefs.hpp>
#endif

#if defined(XML_SUNCC)
#include    <util/Compilers/SunCCDefs.hpp>
#endif

#if defined(XML_SCOCC)
#include    <util/Compilers/SCOCCDefs.hpp>
#endif

#if defined(XML_SOLARIS_KAICC)
#include    <util/Compilers/SunKaiDefs.hpp>
#endif

#if defined(XML_GNUG)
#include    <util/Compilers/GNUGDefs.hpp>
#endif

#if defined(XML_HPUX_CC) || defined(XML_HPUX_aCC) || defined(XML_HPUX_KAICC)
#include    <util/Compilers/HPCCDefs.hpp>
#endif

#if defined(XML_MIPSPRO_CC)
#include    <util/Compilers/MIPSproDefs.hpp>
#endif

#if defined(XML_TANDEMCC)
#include    <util/Compilers/TandemCCDefs.hpp>
#endif

#if defined(XML_GCC)
#include    <util/Compilers/GCCDefs.hpp>
#endif

#if defined(XML_MVSCPP)
#include    <util/Compilers/MVSCPPDefs.hpp>
#endif

#if defined(XML_IBMVAW32)
#include    <util/Compilers/IBMVAW32Defs.hpp>
#endif

#if defined(XML_IBMVAOS2)
#include    <util/Compilers/IBMVAOS2Defs.hpp>
#endif

#if defined(XML_METROWERKS)
#include	<util/Compilers/CodeWarriorDefs.hpp>
#endif

// ---------------------------------------------------------------------------
//  Some general typedefs that are defined for internal flexibility.
//
//  Note  that UTF16Ch is fixed at 16 bits, whereas XMLCh floats in size per
//  platform, to whatever is the native wide char format there. UCS4Ch is
//  fixed at 32 bits. The types we defined them in terms of are defined per
//  compiler, using whatever types are the right ones for them to get these
//  16/32 bit sizes.
// ---------------------------------------------------------------------------
typedef unsigned char       XMLByte;
typedef XMLUInt16           UTF16Ch;
typedef XMLUInt32           UCS4Ch;

// ---------------------------------------------------------------------------
//  Handle boolean. If the platform can handle booleans itself, then we
//  map our boolean type to the native type. Otherwise we create a default
//  one as an int and define const values for true and false.
//
//  This flag will be set in the per-development environment stuff above.
// ---------------------------------------------------------------------------
#if defined(NO_NATIVE_BOOL)
typedef int     bool;
const   bool    true    = 1;
const   bool    false   = 0;
#endif

// ---------------------------------------------------------------------------
//  Set up the import/export keyword  for our core projects. The
//  PLATFORM_XXXX keywords are set in the per-development environment
//  include above.
// ---------------------------------------------------------------------------
#if defined(PROJ_XMLUTIL)
#define XMLUTIL_EXPORT PLATFORM_EXPORT
#else
#define XMLUTIL_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_XMLPARSER)
#define XMLPARSER_EXPORT PLATFORM_EXPORT
#else
#define XMLPARSER_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_SAX4C)
#define SAX_EXPORT PLATFORM_EXPORT
#else
#define SAX_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_DOM)
#define CDOM_EXPORT PLATFORM_EXPORT
#else
#define CDOM_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_PARSERS)
#define PARSERS_EXPORT  PLATFORM_EXPORT
#else
#define PARSERS_EXPORT  PLATFORM_IMPORT
#endif

#if defined(PROJ_VALIDATORS)
#define VALIDATORS_EXPORT  PLATFORM_EXPORT
#else
#define VALIDATORS_EXPORT  PLATFORM_IMPORT
#endif

#endif
<commit_msg>Updated the version information for the next release, i.e. 1.1.0<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.6  2000/01/14 00:52:06  roddey
 * Updated the version information for the next release, i.e. 1.1.0
 *
 * Revision 1.5  1999/12/17 01:28:53  rahulj
 * Merged in changes submitted for UnixWare 7 port. Platform
 * specific files are still missing.
 *
 * Revision 1.4  1999/12/16 23:47:10  rahulj
 * Updated for version 1.0.1
 *
 * Revision 1.3  1999/12/01 17:16:16  rahulj
 * Added support for IRIX 6.5.5 using SGI MIPSpro C++ 7.3 and 7.21 generating 32 bit objects. Changes submitted by Marc Stuessel
 *
 * Revision 1.2  1999/11/10 02:02:51  abagchi
 * Changed version numbers
 *
 * Revision 1.1.1.1  1999/11/09 01:05:35  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:45:19  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(XML4CDEFS_HPP)
#define XML4CDEFS_HPP

// ---------------------------------------------------------------------------
//  These are the various representations of the current version of XML4C.
//  These are updated for every build. They must be at the top because they
//  can be used by various per-compiler headers below.
// ---------------------------------------------------------------------------
#define XML4C_DLLVersionStr "1_1"
static const char* const    gXML4CVersionStr = "1_1";
static const char* const    gXML4CFullVersionStr = "1_1_0";
static const unsigned int   gXML4CMajVersion = 1;
static const unsigned int   gXML4CMinVersion = 1;
static const unsigned int   gXML4CRevision   = 0;

// ---------------------------------------------------------------------------
//  Include the header that does automatic sensing of the current platform
//  and compiler.
// ---------------------------------------------------------------------------
#include    <util/AutoSense.hpp>

// ---------------------------------------------------------------------------
//  According to the platform we include a platform specific file. This guy
//  will set up any platform specific stuff, such as character mode.
// ---------------------------------------------------------------------------
#if defined(XML_WIN32)
#include    <util/Platforms/Win32/Win32Defs.hpp>
#endif

#if defined(XML_AIX)
#include    <util/Platforms/AIX/AIXDefs.hpp>
#endif

#if defined(XML_SOLARIS)
#include    <util/Platforms/Solaris/SolarisDefs.hpp>
#endif

#if defined(XML_UNIXWARE)
#include    <util/Platforms/UnixWare/UnixWareDefs.hpp>
#endif

#if defined(XML_HPUX)
#include    <util/Platforms/HPUX/HPUXDefs.hpp>
#endif

#if defined(XML_IRIX)
#include    <util/Platforms/IRIX/IRIXDefs.hpp>
#endif

#if defined(XML_TANDEM)
#include    <util/Platforms/Tandem/TandemDefs.hpp>
#endif

#if defined(XML_LINUX)
#include    <util/Platforms/Linux/LinuxDefs.hpp>
#endif

#if defined(XML_OE390)
#include    <util/Platforms/OS390/OE390Defs.hpp>
#endif

#if defined(XML_OS2)
#include    <util/Platforms/OS2/OS2Defs.hpp>
#endif

#if defined(XML_MACOS)
#include	<util/Platforms/MaxOS/MacOSDefs.hpp>
#endif

// ---------------------------------------------------------------------------
//  And now we subinclude a header according to the development environment
//  we are on. This guy defines for each platform some basic stuff that is
//  specific to the development environment.
// ---------------------------------------------------------------------------
#if defined(XML_VISUALCPP)
#include    <util/Compilers/VCPPDefs.hpp>
#endif

#if defined(XML_CSET)
#include    <util/Compilers/CSetDefs.hpp>
#endif

#if defined(XML_BORLAND)
#include    <util/Compilers/BorlandCDefs.hpp>
#endif

#if defined(XML_SUNCC)
#include    <util/Compilers/SunCCDefs.hpp>
#endif

#if defined(XML_SCOCC)
#include    <util/Compilers/SCOCCDefs.hpp>
#endif

#if defined(XML_SOLARIS_KAICC)
#include    <util/Compilers/SunKaiDefs.hpp>
#endif

#if defined(XML_GNUG)
#include    <util/Compilers/GNUGDefs.hpp>
#endif

#if defined(XML_HPUX_CC) || defined(XML_HPUX_aCC) || defined(XML_HPUX_KAICC)
#include    <util/Compilers/HPCCDefs.hpp>
#endif

#if defined(XML_MIPSPRO_CC)
#include    <util/Compilers/MIPSproDefs.hpp>
#endif

#if defined(XML_TANDEMCC)
#include    <util/Compilers/TandemCCDefs.hpp>
#endif

#if defined(XML_GCC)
#include    <util/Compilers/GCCDefs.hpp>
#endif

#if defined(XML_MVSCPP)
#include    <util/Compilers/MVSCPPDefs.hpp>
#endif

#if defined(XML_IBMVAW32)
#include    <util/Compilers/IBMVAW32Defs.hpp>
#endif

#if defined(XML_IBMVAOS2)
#include    <util/Compilers/IBMVAOS2Defs.hpp>
#endif

#if defined(XML_METROWERKS)
#include	<util/Compilers/CodeWarriorDefs.hpp>
#endif

// ---------------------------------------------------------------------------
//  Some general typedefs that are defined for internal flexibility.
//
//  Note  that UTF16Ch is fixed at 16 bits, whereas XMLCh floats in size per
//  platform, to whatever is the native wide char format there. UCS4Ch is
//  fixed at 32 bits. The types we defined them in terms of are defined per
//  compiler, using whatever types are the right ones for them to get these
//  16/32 bit sizes.
// ---------------------------------------------------------------------------
typedef unsigned char       XMLByte;
typedef XMLUInt16           UTF16Ch;
typedef XMLUInt32           UCS4Ch;

// ---------------------------------------------------------------------------
//  Handle boolean. If the platform can handle booleans itself, then we
//  map our boolean type to the native type. Otherwise we create a default
//  one as an int and define const values for true and false.
//
//  This flag will be set in the per-development environment stuff above.
// ---------------------------------------------------------------------------
#if defined(NO_NATIVE_BOOL)
typedef int     bool;
const   bool    true    = 1;
const   bool    false   = 0;
#endif

// ---------------------------------------------------------------------------
//  Set up the import/export keyword  for our core projects. The
//  PLATFORM_XXXX keywords are set in the per-development environment
//  include above.
// ---------------------------------------------------------------------------
#if defined(PROJ_XMLUTIL)
#define XMLUTIL_EXPORT PLATFORM_EXPORT
#else
#define XMLUTIL_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_XMLPARSER)
#define XMLPARSER_EXPORT PLATFORM_EXPORT
#else
#define XMLPARSER_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_SAX4C)
#define SAX_EXPORT PLATFORM_EXPORT
#else
#define SAX_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_DOM)
#define CDOM_EXPORT PLATFORM_EXPORT
#else
#define CDOM_EXPORT PLATFORM_IMPORT
#endif

#if defined(PROJ_PARSERS)
#define PARSERS_EXPORT  PLATFORM_EXPORT
#else
#define PARSERS_EXPORT  PLATFORM_IMPORT
#endif

#if defined(PROJ_VALIDATORS)
#define VALIDATORS_EXPORT  PLATFORM_EXPORT
#else
#define VALIDATORS_EXPORT  PLATFORM_IMPORT
#endif

#endif
<|endoftext|>


<commit_before>#include"line.hpp"

<commit_msg>In Progress Code for Fitting Splines<commit_after>#include"line.hpp"
#include"spline.hpp"

bool debug_spline = false;

void  matrix_multiplication_spline(float* arr1, int arr1_rows, int arr1_cols, float* arr2, int arr2_rows, int arr2_cols, float* r_arr)
{
	for(int i = 0;i<arr1_rows;i++)
	{
		for(int j = 0;j < arr2_cols;j++)
		{
			*(r_arr + i*arr2_cols + j) = 0;
			for(int k =0;k<arr1_cols;k++)
			{
				*(r_arr + i*arr2_cols + j) = *(r_arr + i*arr2_cols +j) + (*(arr1+ i*arr1_cols + k))*(*(arr2 + k*arr2_cols + j));
			}

		}
	}

}

void getRansacSplines(vector<Line>& line_objects, vector<Spline>& spline_objects, Mat& gray_ipm_image)
{
	for(int i  = 0;i<line_objects.size();i++)
	{

		Spline spline = getLine2Spline(line_objects[i], DEGREE);
		spline_objects[i] = spline;

	}

	//fitSpline(spline_objects);
	drawSpline(gray_ipm_image, spline_objects);

}

void drawSpline(Mat& gray_ipm_image, vector<Spline>& spline_objects)
{
	for(int i =0;i<spline_objects.size();i++)
	{
			getSplinePoints(spline_objects[i],.05);

	}

}

void getSplinePoints(Spline& spline, float resolution)
{
	float* tangents = (float*)malloc(2*2*sizeof(float));
	float* points = evaluateSpline(spline, resolution, tangents);

	if(debug_spline)
	{
		for(int i = 0;i<2;i++)
		{
			for(int j = 0;j<2;j++)
			{
				cout<<*(tangents + i*2 + j)<<"\t";
			}
			cout<<endl;
		}
	}
	if(debug_spline)
	{
		for(int i =0;i<20;i++)
		{
			for(int j =0;j<2;j++)
			{
				cout<<*(points + i*20 +j)<<"\t";
			}
			cout<<endl;
		}
	}

}

float* evaluateSpline(Spline& spline, float resolution, float* tangents)
{
	int n = (int)(1./resolution) + 1;

	float* points = (float*)malloc(n*2*sizeof(float));

	float M3 [] = {-1,3,3,1,3,-6,3,0,-3,3,0,0,1,0,0,0};

	float* spline_points = (float*)malloc((spline.degree + 1)*2*sizeof(float));
	float P[2], dP[2], ddP[2], dddP[2];
	float h2 = resolution*resolution;
	float h3 = resolution*h2;

	for(int i =0;i<(spline.degree +1);i++)
	{
		*(spline_points + i*2) = (float) spline.points[i].x;
		*(spline_points + i*2 + 1) = (float) spline.points[i].y;

	}

	if(debug_spline)
	{
		for(int i = 0;i<(spline.degree + 1);i++)
		{
			for(int j =0;j<2;j++)
			{
				cout<<"Coordinates \t"<<*(spline_points +i*(2) + j);

			}
			cout<<endl;
		}
	}

	float* spline_control_points = (float*)malloc((spline.degree + 1)*2*sizeof(float));

	float *M = (float*)malloc(sizeof(float)*4*4);
	memcpy(M, M3, sizeof(float)*4*4);

	if(debug_spline)
	{
		for(int i = 0;i<4;i++)
		{
			for(int j =0;j<4;j++)
			{
				cout<<*(M + i*4 + j)<<"\t";

			}
		cout<<endl;
		}
	}
	matrix_multiplication_spline(M, 4, 4, spline_points, (spline.degree + 1), 2, spline_control_points);

	if(debug_spline)
	{
		for(int i = 0;i<4;i++)
		{
			for(int j =0;j<2;j++)
			{
				cout<<"Points \t"<<*(spline_control_points + i*2 + j)<<"\t";

			}
			cout<<endl;
		}
	}

	int p_col = 2;

	P[0] = *(spline_control_points + 3*p_col);
	P[1] = *(spline_control_points + 3*p_col + 1);

	dP[0] = *(spline_control_points + 2*p_col)*resolution + *(spline_control_points + 1*p_col)*h2 + *(spline_control_points)*h3;
	dP[1] = *(spline_control_points + 2*p_col + 1)*resolution + *(spline_control_points + 1*p_col + 1)*h2 + *(spline_control_points + 1)*h3;

	dddP[0] = 6*(*(spline_control_points))*h3;
	dddP[1] = 6*(*(spline_control_points + 1))*h3;

	ddP[0] = 2*(*(spline_control_points + 1*p_col))*h2 + dddP[0];
	ddP[1] = 2*(*(spline_control_points + 1*p_col + 1))*h2 + dddP[1];

	if(debug_spline)
	{
		cout<<"Number of Points \t"<<n<<endl;
	}

	for(int i = 0;i<n;i++)
	{
		*(points + i*p_col) = P[0];
		*(points + i*p_col + 1) = P[1];

		P[0] += dP[0];
		P[1] += dP[1];
		dP[0] += ddP[0];
		dP[1] += ddP[1];
		ddP[0] += dddP[0];
		ddP[1] += dddP[1];

	}

	if(tangents)
	{
		*(tangents) = *(spline_control_points + 2*p_col);
		*(tangents + 1) = *(spline_control_points + 2*p_col +1);
		*(tangents + 1*p_col) =  3*(*(spline_control_points)) + 2*(*(spline_control_points + 1*p_col)) + *(spline_control_points + 2*p_col);
		*(tangents + 1*p_col) = 3*(*(spline_control_points + 1)) + 2*(*(spline_control_points + 1*p_col + 1)) + *(spline_control_points + 2*p_col + 1);

	}

	return points;

}

/*
void fitSpline(vector<Spline>& spline_objects)
{
	int count_spline_objects = spline_objects.size();
	for(int i  = 0;i<count_spline_objects;i++)
	{
		fitbezierSpline(spline_objects[i].spline_x_y_points);

	}

}
*/

Spline getLine2Spline(Line& line_object, int degree)
{

	Spline spline;
	spline.degree = 3;

	spline.points[0] = line_object.startpoint;
	spline.points[degree] = line_object.endpoint;

	Linepoint direction = getDirection(line_object.endpoint, line_object.startpoint);

	for(int i = 1;i<degree;i++)
	{
		Linepoint point;
		float t = i/(float) degree;
		point.x = line_object.startpoint.x + t*direction.x;
		point.y = line_object.startpoint.y + t*direction.y;

		spline.points[i] = point;

	}
	spline.spline_x_y_points = line_object.x_y_points;

	if(debug_spline)
	{
		for(int i =0;i<4;i++)
		{
			cout<<"Coordinates \t"<<spline.points[i].x<<"\t"<<spline.points[i].y<<endl;

		}
	}

	return spline;

}

Linepoint getDirection(const Linepoint& v1, const Linepoint& v2)
{
	Linepoint dir = {v1.x - v2.x, v1.y - v2.y};
	return dir;

}

/*
void fitbezierSpline(vector<Linepoint>& spline_x_y_points, int degree)
{

}
*/

<|endoftext|>


<commit_before>// t0513.cc
// sizeof a struct with a bitfield

struct S1 {
  unsigned x : 2;
  unsigned y : 30;
};

int arr1[sizeof(S1)==4? +1 : -1];

struct S2 {
  unsigned x : 2;
  unsigned y : 30;
  unsigned z : 1;
};

// edg and icc both say this is 8 ...
int arr2[sizeof(S2)==8? +1 : -1];

// this is from a header file somewhere, it shows up in quite a
// few of the Debian build failures
struct real_value {
  unsigned int canonical : 1;                       // 1
  signed int exp : (32 - 5);                        // 27
  unsigned long sig[((128 + (8 * 4)) / (8 * 4))];   // 5
};

extern char test_real_width [
  sizeof(struct real_value) <= (((128 + (8 * 4)) + 32)/(8 * 4) + (((128 + (8 * 4)) + 32)%(8 * 4) ? 1 : 0))*sizeof(long) ? 1 : -1
];
<commit_msg>tweak<commit_after>// t0513.cc
// sizeof a struct with a bitfield

struct S1 {
  unsigned x : 2;
  unsigned y : 30;
};

int arr1[sizeof(S1)==4? +1 : -1];

struct S2 {
  unsigned x : 2;
  unsigned y : 30;
  unsigned z : 1;
};

// edg and icc both say this is 8 ...
int arr2[sizeof(S2)==8? +1 : -1];

// this is from a header file somewhere, it shows up in quite a
// few of the Debian build failures
//
// actually, it's gcc's implementation of __real__, and then a
// check regarding its size (because gcc must emit machine code
// to manipulate it), and this appears in both gcc and mingw32
struct real_value {
  unsigned int canonical : 1;                       // 1
  signed int exp : (32 - 5);                        // 27
  unsigned long sig[((128 + (8 * 4)) / (8 * 4))];   // 5
};

extern char test_real_width [
  sizeof(struct real_value) <= (((128 + (8 * 4)) + 32)/(8 * 4) + (((128 + (8 * 4)) + 32)%(8 * 4) ? 1 : 0))*sizeof(long) ? 1 : -1
];
<|endoftext|>


<commit_before>#include "nanocv.h"
#include "grid_image.h"
#include <boost/program_options.hpp>
#include <algorithm>

int main(int argc, char *argv[])
{
        ncv::init();

        using namespace ncv;

        // prepare object string-based selection
        const strings_t task_ids = task_manager_t::instance().ids();
        const strings_t loss_ids = loss_manager_t::instance().ids();
        const strings_t model_ids = model_manager_t::instance().ids();

        // parse the command line
        boost::program_options::options_description po_desc("", 160);
        po_desc.add_options()("help,h", "help message");
        po_desc.add_options()("task",
                boost::program_options::value<string_t>(),
                text::concatenate(task_ids, ", ").c_str());
        po_desc.add_options()("task-dir",
                boost::program_options::value<string_t>(),
                "directory to load task data from");
        po_desc.add_options()("loss",
                boost::program_options::value<string_t>(),
                text::concatenate(loss_ids, ", ").c_str());
        po_desc.add_options()("model",
                boost::program_options::value<string_t>(),
                text::concatenate(model_ids, ", ").c_str());
        po_desc.add_options()("model-file",
                boost::program_options::value<string_t>(),
                "filepath to load the model from");
        po_desc.add_options()("save-dir",
                boost::program_options::value<string_t>(),
                "directory to save classification results to");
        po_desc.add_options()("save-group-rows",
                boost::program_options::value<size_t>()->default_value(32),
                "number of samples to group in a row");
        po_desc.add_options()("save-group-cols",
                boost::program_options::value<size_t>()->default_value(32),
                "number of samples to group in a column");

        boost::program_options::variables_map po_vm;
        boost::program_options::store(
                boost::program_options::command_line_parser(argc, argv).options(po_desc).run(),
                po_vm);
        boost::program_options::notify(po_vm);

        // check arguments and options
        if (	po_vm.empty() ||
                !po_vm.count("task") ||
                !po_vm.count("task-dir") ||
                !po_vm.count("loss") ||
                !po_vm.count("model") ||
                !po_vm.count("model-file") ||
                po_vm.count("help"))
        {
                std::cout << po_desc;
                return EXIT_FAILURE;
        }

        const string_t cmd_task = po_vm["task"].as<string_t>();
        const string_t cmd_task_dir = po_vm["task-dir"].as<string_t>();
        const string_t cmd_loss = po_vm["loss"].as<string_t>();
        const string_t cmd_model = po_vm["model"].as<string_t>();
        const string_t cmd_input = po_vm["model-file"].as<string_t>();
        const string_t cmd_save_dir = po_vm.count("save-dir") ? po_vm["save-dir"].as<string_t>() : "";
        const size_t cmd_save_group_rows = math::clamp(po_vm["save-group-rows"].as<size_t>(), 1, 128);
        const size_t cmd_save_group_cols = math::clamp(po_vm["save-group-cols"].as<size_t>(), 1, 128);

        // create task
        const rtask_t rtask = task_manager_t::instance().get(cmd_task);

        // load task data
        ncv::measure_critical_call(
                [&] () { return rtask->load(cmd_task_dir); },
                "loaded task",
                "failed to load task <" + cmd_task + "> from directory <" + cmd_task_dir + ">");

        // describe task
        log_info() << "images: " << rtask->n_images() << ".";
        log_info() << "sample: #rows = " << rtask->n_rows()
                   << ", #cols = " << rtask->n_cols()
                   << ", #outputs = " << rtask->n_outputs()
                   << ", #folds = " << rtask->n_folds() << ".";

        for (size_t f = 0; f < rtask->n_folds(); f ++)
        {
                sampler_t trsampler(*rtask), tesampler(*rtask);
                trsampler.setup(fold_t{f, protocol::train});
                tesampler.setup(fold_t{f, protocol::test});

                log_info() << "fold [" << (f + 1) << "/" << rtask->n_folds()
                           << "]: #train samples = " << trsampler.size()
                           << ", #test samples = " << tesampler.size() << ".";
        }

        // create loss
        const rloss_t rloss = loss_manager_t::instance().get(cmd_loss);

        // create model
        const rmodel_t rmodel = model_manager_t::instance().get(cmd_model);

        // load model
        ncv::measure_critical_call(
                [&] () { return rmodel->load(cmd_input); },
                "loaded model",
                "failed to load model from <" + cmd_input + ">");

        // test model
        stats_t<scalar_t> lstats, estats;
        for (size_t f = 0; f < rtask->n_folds(); f ++)
        {
                const fold_t test_fold = std::make_pair(f, protocol::test);

                const ncv::timer_t timer;
                scalar_t lvalue, lerror;
                ncv::test(*rtask, test_fold, *rloss, *rmodel, lvalue, lerror);
                log_info() << "<<< test error: [" << lvalue << "/" << lerror << "] in " << timer.elapsed() << ".";

                lstats(lvalue);
                estats(lerror);
        }

        // performance statistics
        log_info() << ">>> performance: loss value = " << lstats.avg() << " +/- " << lstats.stdev()
                   << " in [" << lstats.min() << ", " << lstats.max() << "].";
        log_info() << ">>> performance: loss error = " << estats.avg() << " +/- " << estats.stdev()
                   << " in [" << estats.min() << ", " << estats.max() << "].";

        // save classification results
        if (!cmd_save_dir.empty())
        {
                for (size_t f = 0; f < rtask->n_folds(); f ++)
                {
                        const fold_t test_fold = std::make_pair(f, protocol::test);

                        sampler_t sampler(*rtask);
                        sampler.setup(test_fold);
                        sampler.setup(sampler_t::atype::annotated);
                        sampler.setup(sampler_t::stype::batch);

                        const samples_t samples = sampler.get();

                        // split test samples into correctly classified & miss-classified
                        samples_t ok_samples;
                        samples_t nk_samples;

                        for (size_t s = 0; s < samples.size(); s ++)
                        {
                                const sample_t& sample = samples[s];
                                const image_t& image = rtask->image(sample.m_index);

                                const vector_t target = sample.m_target;
                                const vector_t output = rmodel->output(image, sample.m_region).vector();

                                const indices_t tclasses = ncv::classes(target);
                                const indices_t oclasses = ncv::classes(output);

                                const bool ok =
                                         tclasses.size() == oclasses.size() &&
                                         std::mismatch(tclasses.begin(), tclasses.end(),
                                                       oclasses.begin()).first == tclasses.end();

                                (ok ? ok_samples : nk_samples).push_back(sample);
                        }

                        const string_t basepath = cmd_save_dir + "/" + cmd_task + "_test_fold" + text::to_string(f + 1);

                        const size_t grows = cmd_save_group_rows;
                        const size_t gcols = cmd_save_group_cols;

                        const rgba_t ok_bkcolor = color::make_rgba(0, 225, 0);
                        const rgba_t nk_bkcolor = color::make_rgba(225, 0, 0);

                        // further split them by label
                        const strings_t labels = rtask->labels();
                        for (const string_t& label : labels)
                        {
                                const string_t lbasepath = basepath + "_" + label;

                                sampler_t ok_sampler(ok_samples); ok_sampler.setup(label);
                                sampler_t nk_sampler(nk_samples); nk_sampler.setup(label);
                                sampler_t ll_sampler(samples); ll_sampler.setup(label);

                                const samples_t ok_samples = ok_sampler.get();
                                const samples_t nk_samples = nk_sampler.get();
                                const sampler_t ll_samples = ll_sampler.get();

                                log_info() << "miss-classified " << nk_samples.size()
                                           << "/" << ll_samples.size() << " [" << label << "] samples.";

                                rtask->save_as_images(ok_samples, lbasepath + "_ok", grows, gcols, 8, ok_bkcolor);
                                rtask->save_as_images(nk_samples, lbasepath + "_nk", grows, gcols, 8, nk_bkcolor);
                        }
                }
        }

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<commit_msg>compute the number of miss-matches (globally & per label)<commit_after>#include "nanocv.h"
#include "grid_image.h"
#include <boost/program_options.hpp>
#include <algorithm>

int main(int argc, char *argv[])
{
        ncv::init();

        using namespace ncv;

        // prepare object string-based selection
        const strings_t task_ids = task_manager_t::instance().ids();
        const strings_t loss_ids = loss_manager_t::instance().ids();
        const strings_t model_ids = model_manager_t::instance().ids();

        // parse the command line
        boost::program_options::options_description po_desc("", 160);
        po_desc.add_options()("help,h", "help message");
        po_desc.add_options()("task",
                boost::program_options::value<string_t>(),
                text::concatenate(task_ids, ", ").c_str());
        po_desc.add_options()("task-dir",
                boost::program_options::value<string_t>(),
                "directory to load task data from");
        po_desc.add_options()("loss",
                boost::program_options::value<string_t>(),
                text::concatenate(loss_ids, ", ").c_str());
        po_desc.add_options()("model",
                boost::program_options::value<string_t>(),
                text::concatenate(model_ids, ", ").c_str());
        po_desc.add_options()("model-file",
                boost::program_options::value<string_t>(),
                "filepath to load the model from");
        po_desc.add_options()("save-dir",
                boost::program_options::value<string_t>(),
                "directory to save classification results to");
        po_desc.add_options()("save-group-rows",
                boost::program_options::value<size_t>()->default_value(32),
                "number of samples to group in a row");
        po_desc.add_options()("save-group-cols",
                boost::program_options::value<size_t>()->default_value(32),
                "number of samples to group in a column");

        boost::program_options::variables_map po_vm;
        boost::program_options::store(
                boost::program_options::command_line_parser(argc, argv).options(po_desc).run(),
                po_vm);
        boost::program_options::notify(po_vm);

        // check arguments and options
        if (	po_vm.empty() ||
                !po_vm.count("task") ||
                !po_vm.count("task-dir") ||
                !po_vm.count("loss") ||
                !po_vm.count("model") ||
                !po_vm.count("model-file") ||
                po_vm.count("help"))
        {
                std::cout << po_desc;
                return EXIT_FAILURE;
        }

        const string_t cmd_task = po_vm["task"].as<string_t>();
        const string_t cmd_task_dir = po_vm["task-dir"].as<string_t>();
        const string_t cmd_loss = po_vm["loss"].as<string_t>();
        const string_t cmd_model = po_vm["model"].as<string_t>();
        const string_t cmd_input = po_vm["model-file"].as<string_t>();
        const string_t cmd_save_dir = po_vm.count("save-dir") ? po_vm["save-dir"].as<string_t>() : "";
        const size_t cmd_save_group_rows = math::clamp(po_vm["save-group-rows"].as<size_t>(), 1, 128);
        const size_t cmd_save_group_cols = math::clamp(po_vm["save-group-cols"].as<size_t>(), 1, 128);

        // create task
        const rtask_t rtask = task_manager_t::instance().get(cmd_task);

        // load task data
        ncv::measure_critical_call(
                [&] () { return rtask->load(cmd_task_dir); },
                "loaded task",
                "failed to load task <" + cmd_task + "> from directory <" + cmd_task_dir + ">");

        // describe task
        log_info() << "images: " << rtask->n_images() << ".";
        log_info() << "sample: #rows = " << rtask->n_rows()
                   << ", #cols = " << rtask->n_cols()
                   << ", #outputs = " << rtask->n_outputs()
                   << ", #folds = " << rtask->n_folds() << ".";

        for (size_t f = 0; f < rtask->n_folds(); f ++)
        {
                sampler_t trsampler(*rtask), tesampler(*rtask);
                trsampler.setup(fold_t{f, protocol::train});
                tesampler.setup(fold_t{f, protocol::test});

                log_info() << "fold [" << (f + 1) << "/" << rtask->n_folds()
                           << "]: #train samples = " << trsampler.size()
                           << ", #test samples = " << tesampler.size() << ".";
        }

        // create loss
        const rloss_t rloss = loss_manager_t::instance().get(cmd_loss);

        // create model
        const rmodel_t rmodel = model_manager_t::instance().get(cmd_model);

        // load model
        ncv::measure_critical_call(
                [&] () { return rmodel->load(cmd_input); },
                "loaded model",
                "failed to load model from <" + cmd_input + ">");

        // test model
        stats_t<scalar_t> lstats, estats;
        for (size_t f = 0; f < rtask->n_folds(); f ++)
        {
                const fold_t test_fold = std::make_pair(f, protocol::test);

		// error rate
                const ncv::timer_t timer;
                scalar_t lvalue, lerror;
                ncv::test(*rtask, test_fold, *rloss, *rmodel, lvalue, lerror);
                log_info() << "<<< test error: [" << lvalue << "/" << lerror << "] in " << timer.elapsed() << ".";

                lstats(lvalue);
                estats(lerror);

		// per-label error rates
		sampler_t sampler(*rtask);
                sampler.setup(test_fold);
                sampler.setup(sampler_t::atype::annotated);
                sampler.setup(sampler_t::stype::batch);

                const samples_t samples = sampler.get();

                // split test samples into correctly classified & miss-classified
                samples_t ok_samples;
                samples_t nk_samples;

                for (size_t s = 0; s < samples.size(); s ++)
                {
                        const sample_t& sample = samples[s];
                        const image_t& image = rtask->image(sample.m_index);

                        const vector_t target = sample.m_target;
                        const vector_t output = rmodel->output(image, sample.m_region).vector();

                        const indices_t tclasses = ncv::classes(target);
                        const indices_t oclasses = ncv::classes(output);

                        const bool ok =
                                        tclasses.size() == oclasses.size() &&
                                        std::mismatch(tclasses.begin(), tclasses.end(),
                                                oclasses.begin()).first == tclasses.end();

                        (ok ? ok_samples : nk_samples).push_back(sample);
                }

                log_info() << "miss-classified " << nk_samples.size() << "/" << (samples.size())
                           << " = " << ((0.0 + nk_samples.size()) / (0.0 + samples.size())) << ".";

                // save classification results
                if (!cmd_save_dir.empty())
                {
                        const string_t basepath = cmd_save_dir + "/" + cmd_task + "_test_fold" + text::to_string(f + 1);

                        const size_t grows = cmd_save_group_rows;
                        const size_t gcols = cmd_save_group_cols;

                        const rgba_t ok_bkcolor = color::make_rgba(0, 225, 0);
                        const rgba_t nk_bkcolor = color::make_rgba(225, 0, 0);

                        // further split them by label
                        const strings_t labels = rtask->labels();
                        for (const string_t& label : labels)
                        {
                                const string_t lbasepath = basepath + "_" + label;

                                sampler_t ok_sampler(ok_samples); ok_sampler.setup(label);
                                sampler_t nk_sampler(nk_samples); nk_sampler.setup(label);
                                sampler_t ll_sampler(samples); ll_sampler.setup(label);

                                const samples_t ok_samples = ok_sampler.get();
                                const samples_t nk_samples = nk_sampler.get();
                                const sampler_t ll_samples = ll_sampler.get();

                                log_info() << "miss-classified " << nk_samples.size()
                                           << "/" << ll_samples.size()
                                           << " = " << ((100.0 * nk_samples.size()) / (0.0 + ll_samples.size()))
                                           << " [" << label << "] samples.";

                                rtask->save_as_images(ok_samples, lbasepath + "_ok", grows, gcols, 8, ok_bkcolor);
                                rtask->save_as_images(nk_samples, lbasepath + "_nk", grows, gcols, 8, nk_bkcolor);
                        }
                }
        }

        // performance statistics
        log_info() << ">>> performance: loss value = " << lstats.avg() << " +/- " << lstats.stdev()
                   << " in [" << lstats.min() << ", " << lstats.max() << "].";
        log_info() << ">>> performance: loss error = " << estats.avg() << " +/- " << estats.stdev()
                   << " in [" << estats.min() << ", " << estats.max() << "].";

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// qual_aux.cc
// some auxillary functions for cc_qual.ast

#include "cc.ast.gen.h"       // C++ AST

void TypeSpecifier::printExtras_Q(ostream &os, int indent) const
{
  xassert(q);
  if (q->ql) {
    ind(os, indent);
    os << q->literalsToString() << endl;
  }
}

char const *TS_name::getTypeName() const
{
  return name->getName();
}

char const *TS_elaborated::getTypeName() const
{
  return name->getName();
}

char const *TS_classSpec::getTypeName() const
{
  return name? name->getName() : "anonymous_TypeSpecifier";
}

char const *TS_enumSpec::getTypeName() const
{
  return name? name : "anonymous_TypeSpecifier";
}

// sm: I reproduced most of the same names that dsw was using
// for these names though there were a couple of inconsistencies
// that I had to remove
char const *TS_simple::getTypeName() const
{
  switch (id) {
    default: xfailure("bad code");
    case ST_CHAR:               return "anonymous_char";
    case ST_UNSIGNED_CHAR:      return "anonymous_unsigned_char";
    case ST_SIGNED_CHAR:        return "anonymous_signed_char";
    case ST_BOOL:               return "anonymous_bool";
    case ST_INT:                return "anonymous_int";
    case ST_UNSIGNED_INT:       return "anonymous_unsigned_int";
    case ST_LONG_INT:           return "anonymous_long_int";
    case ST_UNSIGNED_LONG_INT:  return "anonymous_unsigned_long_int";
    case ST_LONG_LONG:          return "anonymous_long_long";
    case ST_UNSIGNED_LONG_LONG: return "anonymous_unsigned_long_long";
    case ST_SHORT_INT:          return "anonymous_short_int";
    case ST_UNSIGNED_SHORT_INT: return "anonymous_unsigned_short_int";
    case ST_WCHAR_T:            return "anonymous_wchar_t";
    case ST_FLOAT:              return "anonymous_float";
    case ST_DOUBLE:             return "anonymous_double";
    case ST_LONG_DOUBLE:        return "anonymous_long_double";
    case ST_VOID:               return "anonymous_void";
    case ST_ELLIPSIS:           return "anonymous_ellipsis";
    case ST_CDTOR:              return "<cdtor>";
    case ST_ERROR:              return "<error>";
    case ST_DEPENDENT:          return "<dependent>";
  }
}

<commit_msg>moving qual_aux.cc to cc_qual; not added there yet<commit_after><|endoftext|>


<commit_before>/** @file

  A simple remap plugin for ATS

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

  @section description
    This is a very simple plugin: it will add headers that are specified on a remap line

    Example usage:
    map /foo http://127.0.0.1/ @plugin=remap_header_add.so @pparam=foo:"x" @pparam=@test:"c" @pparam=a:"b"

 */
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include "ts/ts.h"
#include "ts/remap.h"

struct remap_line {
  int argc;
  char **argv; // store the originals

  int nvc;     // the number of name value pairs, should be argc - 2.
  char **name; // at load we will parse out the name and values.
  char **val;
};

#define TAG "headeradd_remap"
#define NOWARN_UNUSED __attribute__((unused))
#define EXTERN extern "C"

EXTERN void
ParseArgIntoNv(const char *arg, char **n, char **v)
{
  const char *colon_pos = strchr(arg, ':');

  if (colon_pos == nullptr) {
    *n = nullptr;
    *v = nullptr;
    TSDebug(TAG, "No name value pair since it was malformed");
    return;
  }

  size_t name_len = colon_pos - arg;
  *n              = (char *)TSmalloc(name_len + 1);
  memcpy(*n, arg, colon_pos - arg);
  (*n)[name_len] = '\0';

  size_t val_len = strlen(colon_pos + 1); // skip past the ':'

  // check to see if the value is quoted.
  if (val_len > 1 && colon_pos[1] == '"' && colon_pos[val_len] == '"') {
    colon_pos++;  // advance past the first quote
    val_len -= 2; // don't include the trailing quote
  }

  *v = (char *)TSmalloc(val_len + 1);
  memcpy(*v, colon_pos + 1, val_len);
  (*v)[val_len] = '\0';

  TSDebug(TAG, "\t name_len=%zu, val_len=%zu, %s=%s", name_len, val_len, *n, *v);
}

TSReturnCode
TSRemapInit(NOWARN_UNUSED TSRemapInterface *api_info, NOWARN_UNUSED char *errbuf, NOWARN_UNUSED int errbuf_size)
{
  return TS_SUCCESS;
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **ih, NOWARN_UNUSED char *errbuf, NOWARN_UNUSED int errbuf_size)
{
  remap_line *rl = nullptr;

  TSDebug(TAG, "TSRemapNewInstance()");

  if (!argv || !ih) {
    TSError("[remap_header_add] Unable to load plugin because missing argv or ih.");
    return TS_ERROR;
  }

  // print all arguments for this particular remapping

  rl       = (remap_line *)TSmalloc(sizeof(remap_line));
  rl->argc = argc;
  rl->argv = argv;
  rl->nvc  = argc - 2; // the first two are the remap from and to
  if (rl->nvc) {
    rl->name = (char **)TSmalloc(sizeof(char *) * rl->nvc);
    rl->val  = (char **)TSmalloc(sizeof(char *) * rl->nvc);
  }

  TSDebug(TAG, "NewInstance:");
  for (int i = 2; i < argc; i++) {
    ParseArgIntoNv(argv[i], &rl->name[i - 2], &rl->val[i - 2]);
  }

  *ih = (void *)rl;

  return TS_SUCCESS;
}

void
TSRemapDeleteInstance(void *ih)
{
  TSDebug(TAG, "deleting instance %p", ih);

  if (ih) {
    remap_line *rl = (remap_line *)ih;
    for (int i = 0; i < rl->nvc; ++i) {
      TSfree(rl->name[i]);
      TSfree(rl->val[i]);
    }

    TSfree(rl->name);
    TSfree(rl->val);
    TSfree(rl);
  }
}

TSRemapStatus
TSRemapDoRemap(void *ih, NOWARN_UNUSED TSHttpTxn txn, NOWARN_UNUSED TSRemapRequestInfo *rri)
{
  remap_line *rl = (remap_line *)ih;

  if (!rl || !rri) {
    TSError("[remap_header_add] rl or rri is null.");
    return TSREMAP_NO_REMAP;
  }

  TSDebug(TAG, "TSRemapDoRemap:");

  TSMBuffer req_bufp;
  TSMLoc req_loc;
  if (TSHttpTxnClientReqGet(txn, &req_bufp, &req_loc) != TS_SUCCESS) {
    TSError("[remap_header_add] Error while retrieving client request header");
    return TSREMAP_NO_REMAP;
  }

  for (int i = 0; i < rl->nvc; ++i) {
    TSDebug(TAG, R"(Attaching header "%s" with value "%s".)", rl->name[i], rl->val[i]);

    TSMLoc field_loc;
    if (TSMimeHdrFieldCreate(req_bufp, req_loc, &field_loc) == TS_SUCCESS) {
      TSMimeHdrFieldNameSet(req_bufp, req_loc, field_loc, rl->name[i], strlen(rl->name[i]));
      TSMimeHdrFieldAppend(req_bufp, req_loc, field_loc);
      TSMimeHdrFieldValueStringInsert(req_bufp, req_loc, field_loc, 0, rl->val[i], strlen(rl->val[i]));
    } else {
      TSError("[remap_header_add] Failure on TSMimeHdrFieldCreate");
    }
  }

  return TSREMAP_NO_REMAP;
}
<commit_msg>TS-4976: Regularize plugins - remap_header_add<commit_after>/** @file

  A simple remap plugin for ATS

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

  @section description
    This is a very simple plugin: it will add headers that are specified on a remap line

    Example usage:
    map /foo http://127.0.0.1/ @plugin=remap_header_add.so @pparam=foo:"x" @pparam=@test:"c" @pparam=a:"b"

 */
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include "ts/ts.h"
#include "ts/remap.h"

struct remap_line {
  int argc;
  char **argv; // store the originals

  int nvc;     // the number of name value pairs, should be argc - 2.
  char **name; // at load we will parse out the name and values.
  char **val;
};

#define PLUGIN_NAME "headeradd_remap"
#define EXTERN extern "C"

EXTERN void
ParseArgIntoNv(const char *arg, char **n, char **v)
{
  const char *colon_pos = strchr(arg, ':');

  if (colon_pos == nullptr) {
    *n = nullptr;
    *v = nullptr;
    TSDebug(PLUGIN_NAME, "No name value pair since it was malformed");
    return;
  }

  size_t name_len = colon_pos - arg;
  *n              = static_cast<char *>(TSmalloc(name_len + 1));
  memcpy(*n, arg, colon_pos - arg);
  (*n)[name_len] = '\0';

  size_t val_len = strlen(colon_pos + 1); // skip past the ':'

  // check to see if the value is quoted.
  if (val_len > 1 && colon_pos[1] == '"' && colon_pos[val_len] == '"') {
    colon_pos++;  // advance past the first quote
    val_len -= 2; // don't include the trailing quote
  }

  *v = static_cast<char *>(TSmalloc(val_len + 1));
  memcpy(*v, colon_pos + 1, val_len);
  (*v)[val_len] = '\0';

  TSDebug(PLUGIN_NAME, "\t name_len=%zu, val_len=%zu, %s=%s", name_len, val_len, *n, *v);
}

TSReturnCode
TSRemapInit(TSRemapInterface *, char *, int)
{
  return TS_SUCCESS;
}

TSReturnCode
TSRemapNewInstance(int argc, char *argv[], void **ih, char *, int)
{
  remap_line *rl = nullptr;

  TSDebug(PLUGIN_NAME, "TSRemapNewInstance()");

  if (!argv || !ih) {
    TSError("[%s] Unable to load plugin because missing argv or ih.", PLUGIN_NAME);
    return TS_ERROR;
  }

  // print all arguments for this particular remapping

  rl       = (remap_line *)TSmalloc(sizeof(remap_line));
  rl->argc = argc;
  rl->argv = argv;
  rl->nvc  = argc - 2; // the first two are the remap from and to
  if (rl->nvc) {
    rl->name = static_cast<char **>(TSmalloc(sizeof(char *) * rl->nvc));
    rl->val  = static_cast<char **>(TSmalloc(sizeof(char *) * rl->nvc));
  }

  TSDebug(PLUGIN_NAME, "NewInstance:");
  for (int i = 2; i < argc; i++) {
    ParseArgIntoNv(argv[i], &rl->name[i - 2], &rl->val[i - 2]);
  }

  *ih = rl;

  return TS_SUCCESS;
}

void
TSRemapDeleteInstance(void *ih)
{
  TSDebug(PLUGIN_NAME, "deleting instance %p", ih);

  if (ih) {
    remap_line *rl = static_cast<remap_line *>(ih);
    for (int i = 0; i < rl->nvc; ++i) {
      TSfree(rl->name[i]);
      TSfree(rl->val[i]);
    }

    TSfree(rl->name);
    TSfree(rl->val);
    TSfree(rl);
  }
}

TSRemapStatus
TSRemapDoRemap(void *ih, TSHttpTxn txn, TSRemapRequestInfo *rri)
{
  remap_line *rl = static_cast<remap_line *>(ih);

  if (!rl || !rri) {
    TSError("[%s] rl or rri is null.", PLUGIN_NAME);
    return TSREMAP_NO_REMAP;
  }

  TSDebug(PLUGIN_NAME, "TSRemapDoRemap:");

  TSMBuffer req_bufp;
  TSMLoc req_loc;
  if (TSHttpTxnClientReqGet(txn, &req_bufp, &req_loc) != TS_SUCCESS) {
    TSError("[%s] Error while retrieving client request header", PLUGIN_NAME);
    return TSREMAP_NO_REMAP;
  }

  for (int i = 0; i < rl->nvc; ++i) {
    TSDebug(PLUGIN_NAME, R"(Attaching header "%s" with value "%s".)", rl->name[i], rl->val[i]);

    TSMLoc field_loc;
    if (TSMimeHdrFieldCreate(req_bufp, req_loc, &field_loc) == TS_SUCCESS) {
      TSMimeHdrFieldNameSet(req_bufp, req_loc, field_loc, rl->name[i], strlen(rl->name[i]));
      TSMimeHdrFieldAppend(req_bufp, req_loc, field_loc);
      TSMimeHdrFieldValueStringInsert(req_bufp, req_loc, field_loc, 0, rl->val[i], strlen(rl->val[i]));
    } else {
      TSError("[%s] Failure on TSMimeHdrFieldCreate", PLUGIN_NAME);
    }
  }

  return TSREMAP_NO_REMAP;
}
<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/render/normals.hpp
 *
 * Copyright 2014-2019 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef EOS_RENDER_NORMALS_HPP
#define EOS_RENDER_NORMALS_HPP

#include "glm/vec3.hpp"
#include "glm/geometric.hpp"

#include "Eigen/Core"

namespace eos {
namespace render {

/**
 * Calculates the normal of a face (or triangle), i.e. the per-face normal. Returned normal will be unit
 * length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline Eigen::Vector3f compute_face_normal(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1,
                                           const Eigen::Vector3f& v2)
{
    Eigen::Vector3f n = (v1 - v0).cross(v2 - v0); // v0-to-v1 x v0-to-v2
    return n.normalized();
};

/**
 * Calculates the normal of a face (or triangle), i.e. the per-face normal. Returned normal will be unit
 * length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline Eigen::Vector3f compute_face_normal(const Eigen::Vector4f& v0, const Eigen::Vector4f& v1,
                                           const Eigen::Vector4f& v2)
{
    Eigen::Vector4f n = (v1 - v0).cross3(v2 - v0); // v0-to-v1 x v0-to-v2
    return n.head<3>().normalized();
};

/**
 * Calculates the normal of a face (or triangle), i.e. the per-face normal. Returned normal will be unit
 * length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline glm::vec3 compute_face_normal(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2)
{
    glm::vec3 n = glm::cross(v1 - v0, v2 - v0); // v0-to-v1 x v0-to-v2
    n = glm::normalize(n);
    return n;
};

} /* namespace render */
} /* namespace eos */

#endif /* EOS_RENDER_NORMALS_HPP */
<commit_msg>Tweak documentation of normals.hpp a bit<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/render/normals.hpp
 *
 * Copyright 2014-2019 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef EOS_RENDER_NORMALS_HPP
#define EOS_RENDER_NORMALS_HPP

#include "glm/vec3.hpp"
#include "glm/geometric.hpp"

#include "Eigen/Core"

namespace eos {
namespace render {

/**
 * Computes the normal of a face (triangle), i.e. the per-face normal. Returned normal will be unit length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline Eigen::Vector3f compute_face_normal(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1,
                                           const Eigen::Vector3f& v2)
{
    Eigen::Vector3f n = (v1 - v0).cross(v2 - v0); // v0-to-v1 x v0-to-v2
    return n.normalized();
};

/**
 * Computes the normal of a face (triangle), i.e. the per-face normal. Returned normal will be unit length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline Eigen::Vector3f compute_face_normal(const Eigen::Vector4f& v0, const Eigen::Vector4f& v1,
                                           const Eigen::Vector4f& v2)
{
    Eigen::Vector4f n = (v1 - v0).cross3(v2 - v0); // v0-to-v1 x v0-to-v2
    return n.head<3>().normalized();
};

/**
 * Computes the normal of a face (triangle), i.e. the per-face normal. Returned normal will be unit length.
 *
 * Assumes the triangle is given in CCW order, i.e. vertices in counterclockwise order on the screen are
 * front-facing.
 *
 * @param[in] v0 First vertex.
 * @param[in] v1 Second vertex.
 * @param[in] v2 Third vertex.
 * @return The unit-length normal of the given triangle.
 */
inline glm::vec3 compute_face_normal(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2)
{
    glm::vec3 n = glm::cross(v1 - v0, v2 - v0); // v0-to-v1 x v0-to-v2
    n = glm::normalize(n);
    return n;
};

} /* namespace render */
} /* namespace eos */

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


<commit_before>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "tests/test-utils.hh"
#include "tests/cql_test_env.hh"
#include "tests/cql_assertions.hh"

SEASTAR_TEST_CASE(test_secondary_index_regular_column_query) {
    return do_with_cql_env([] (cql_test_env& e) {
        return e.execute_cql("CREATE TABLE users (userid int, name text, email text, country text, PRIMARY KEY (userid));").discard_result().then([&e] {
            return e.execute_cql("CREATE INDEX ON users (email);").discard_result();
        }).then([&e] {
            return e.execute_cql("CREATE INDEX ON users (country);").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (0, 'Bondie Easseby', 'beassebyv@house.gov', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (1, 'Demetri Curror', 'dcurrorw@techcrunch.com', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (2, 'Langston Paulisch', 'lpaulischm@reverbnation.com', 'United States');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (3, 'Channa Devote', 'cdevote14@marriott.com', 'Denmark');").discard_result();
        }).then([&e] {
            return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
        }).then([&e] (shared_ptr<cql_transport::messages::result_message> msg) {
            assert_that(msg).is_rows().with_rows({
                { utf8_type->decompose(sstring("beassebyv@house.gov")) },
                { utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
            });
        });
    });
}

SEASTAR_TEST_CASE(test_secondary_index_clustering_key_query) {
    return do_with_cql_env([] (cql_test_env& e) {
        return e.execute_cql("CREATE TABLE users (userid int, name text, email text, country text, PRIMARY KEY (userid, country));").discard_result().then([&e] {
            return e.execute_cql("CREATE INDEX ON users (country);").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (0, 'Bondie Easseby', 'beassebyv@house.gov', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (1, 'Demetri Curror', 'dcurrorw@techcrunch.com', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (2, 'Langston Paulisch', 'lpaulischm@reverbnation.com', 'United States');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (3, 'Channa Devote', 'cdevote14@marriott.com', 'Denmark');").discard_result();
        }).then([&e] {
            return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
        }).then([&e] (auto msg) {
            assert_that(msg).is_rows().with_rows({
                { utf8_type->decompose(sstring("beassebyv@house.gov")) },
                { utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
            });
        });
    });
}

// CQL usually folds identifier names - keyspace, table and column names -
// to lowercase. That is, unless the identifier is enclosed in double
// quotation marks ("). Let's test that case-sensitive (quoted) column
// names can be indexed. This reproduces issues #3154, #3388, #3391, #3401.
SEASTAR_TEST_CASE(test_secondary_index_case_sensitive) {
    return do_with_cql_env_thread([] (auto& e) {
        // Test case-sensitive *table* name.
        e.execute_cql("CREATE TABLE \"FooBar\" (a int PRIMARY KEY, b int, c int)").get();
        e.execute_cql("CREATE INDEX ON \"FooBar\" (b)").get();
        e.execute_cql("INSERT INTO \"FooBar\" (a, b, c) VALUES (1, 2, 3)").get();
        e.execute_cql("SELECT * from \"FooBar\" WHERE b = 1").get();

        // Test case-sensitive *indexed column* name.
        // This not working was issue #3154. The symptom was that the SELECT
        // below threw a "No index found." runtime error.
        e.execute_cql("CREATE TABLE tab (a int PRIMARY KEY, \"FooBar\" int, c int)").get();
        e.execute_cql("CREATE INDEX ON tab (\"FooBar\")").get();
        // This INSERT also had problems (issue #3401)
        e.execute_cql("INSERT INTO tab (a, \"FooBar\", c) VALUES (1, 2, 3)").get();
        e.execute_cql("SELECT * from tab WHERE \"FooBar\" = 2").get();

        // Test case-sensitive *partition column* name.
        // This used to have multiple bugs in SI and MV code, detailed below:
        e.execute_cql("CREATE TABLE tab2 (\"FooBar\" int PRIMARY KEY, b int, c int)").get();
        e.execute_cql("CREATE INDEX ON tab2 (b)").get();
        // The following INSERT didn't work because of issues #3388 and #3391.
        e.execute_cql("INSERT INTO tab2 (\"FooBar\", b, c) VALUES (1, 2, 3)").get();
        // After the insert works, add the SELECT and see it works. It used
        // to fail before the patch to #3210 fixed this incidentally.
        e.execute_cql("SELECT * from tab2 WHERE b = 2").get();
    });
}

SEASTAR_TEST_CASE(test_cannot_drop_secondary_index_backing_mv) {
    return do_with_cql_env_thread([] (cql_test_env& e) {
        e.execute_cql("create table cf (p int primary key, a int)").get();
        e.execute_cql("create index on cf (a)").get();
        auto s = e.local_db().find_schema(sstring("ks"), sstring("cf"));
        auto index_name = s->index_names().front();
        assert_that_failed(e.execute_cql(sprint("drop materialized view %s_index", index_name)));
    });
}

// Issue #3210 is about searching the secondary index not working properly
// when the *partition key* has multiple columns (a compound partition key),
// and this is what we test here.
SEASTAR_TEST_CASE(test_secondary_index_case_compound_partition_key) {
    return do_with_cql_env_thread([] (auto& e) {
        // Test case-sensitive *table* name.
        e.execute_cql("CREATE TABLE tab (a int, b int, c int, PRIMARY KEY ((a, b)))").get();
        e.execute_cql("CREATE INDEX ON tab (c)").get();
        e.execute_cql("INSERT INTO tab (a, b, c) VALUES (1, 2, 3)").get();
        eventually([&] {
            // We expect this search to find the single row, with the compound
            // partition key (a, b) = (1, 2).
            auto res = e.execute_cql("SELECT * from tab WHERE c = 3").get0();
            assert_that(res).is_rows()
                    .with_size(1)
                    .with_row({
                        {int32_type->decompose(1)},
                        {int32_type->decompose(2)},
                        {int32_type->decompose(3)},
                    });
        });
    });
}
<commit_msg>secondary index: add tests for IF NOT EXISTS, IF EXISTS<commit_after>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "tests/test-utils.hh"
#include "tests/cql_test_env.hh"
#include "tests/cql_assertions.hh"

SEASTAR_TEST_CASE(test_secondary_index_regular_column_query) {
    return do_with_cql_env([] (cql_test_env& e) {
        return e.execute_cql("CREATE TABLE users (userid int, name text, email text, country text, PRIMARY KEY (userid));").discard_result().then([&e] {
            return e.execute_cql("CREATE INDEX ON users (email);").discard_result();
        }).then([&e] {
            return e.execute_cql("CREATE INDEX ON users (country);").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (0, 'Bondie Easseby', 'beassebyv@house.gov', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (1, 'Demetri Curror', 'dcurrorw@techcrunch.com', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (2, 'Langston Paulisch', 'lpaulischm@reverbnation.com', 'United States');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (3, 'Channa Devote', 'cdevote14@marriott.com', 'Denmark');").discard_result();
        }).then([&e] {
            return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
        }).then([&e] (shared_ptr<cql_transport::messages::result_message> msg) {
            assert_that(msg).is_rows().with_rows({
                { utf8_type->decompose(sstring("beassebyv@house.gov")) },
                { utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
            });
        });
    });
}

SEASTAR_TEST_CASE(test_secondary_index_clustering_key_query) {
    return do_with_cql_env([] (cql_test_env& e) {
        return e.execute_cql("CREATE TABLE users (userid int, name text, email text, country text, PRIMARY KEY (userid, country));").discard_result().then([&e] {
            return e.execute_cql("CREATE INDEX ON users (country);").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (0, 'Bondie Easseby', 'beassebyv@house.gov', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (1, 'Demetri Curror', 'dcurrorw@techcrunch.com', 'France');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (2, 'Langston Paulisch', 'lpaulischm@reverbnation.com', 'United States');").discard_result();
        }).then([&e] {
            return e.execute_cql("INSERT INTO users (userid, name, email, country) VALUES (3, 'Channa Devote', 'cdevote14@marriott.com', 'Denmark');").discard_result();
        }).then([&e] {
            return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
        }).then([&e] (auto msg) {
            assert_that(msg).is_rows().with_rows({
                { utf8_type->decompose(sstring("beassebyv@house.gov")) },
                { utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
            });
        });
    });
}

// CQL usually folds identifier names - keyspace, table and column names -
// to lowercase. That is, unless the identifier is enclosed in double
// quotation marks ("). Let's test that case-sensitive (quoted) column
// names can be indexed. This reproduces issues #3154, #3388, #3391, #3401.
SEASTAR_TEST_CASE(test_secondary_index_case_sensitive) {
    return do_with_cql_env_thread([] (auto& e) {
        // Test case-sensitive *table* name.
        e.execute_cql("CREATE TABLE \"FooBar\" (a int PRIMARY KEY, b int, c int)").get();
        e.execute_cql("CREATE INDEX ON \"FooBar\" (b)").get();
        e.execute_cql("INSERT INTO \"FooBar\" (a, b, c) VALUES (1, 2, 3)").get();
        e.execute_cql("SELECT * from \"FooBar\" WHERE b = 1").get();

        // Test case-sensitive *indexed column* name.
        // This not working was issue #3154. The symptom was that the SELECT
        // below threw a "No index found." runtime error.
        e.execute_cql("CREATE TABLE tab (a int PRIMARY KEY, \"FooBar\" int, c int)").get();
        e.execute_cql("CREATE INDEX ON tab (\"FooBar\")").get();
        // This INSERT also had problems (issue #3401)
        e.execute_cql("INSERT INTO tab (a, \"FooBar\", c) VALUES (1, 2, 3)").get();
        e.execute_cql("SELECT * from tab WHERE \"FooBar\" = 2").get();

        // Test case-sensitive *partition column* name.
        // This used to have multiple bugs in SI and MV code, detailed below:
        e.execute_cql("CREATE TABLE tab2 (\"FooBar\" int PRIMARY KEY, b int, c int)").get();
        e.execute_cql("CREATE INDEX ON tab2 (b)").get();
        // The following INSERT didn't work because of issues #3388 and #3391.
        e.execute_cql("INSERT INTO tab2 (\"FooBar\", b, c) VALUES (1, 2, 3)").get();
        // After the insert works, add the SELECT and see it works. It used
        // to fail before the patch to #3210 fixed this incidentally.
        e.execute_cql("SELECT * from tab2 WHERE b = 2").get();
    });
}

SEASTAR_TEST_CASE(test_cannot_drop_secondary_index_backing_mv) {
    return do_with_cql_env_thread([] (cql_test_env& e) {
        e.execute_cql("create table cf (p int primary key, a int)").get();
        e.execute_cql("create index on cf (a)").get();
        auto s = e.local_db().find_schema(sstring("ks"), sstring("cf"));
        auto index_name = s->index_names().front();
        assert_that_failed(e.execute_cql(sprint("drop materialized view %s_index", index_name)));
    });
}

// Issue #3210 is about searching the secondary index not working properly
// when the *partition key* has multiple columns (a compound partition key),
// and this is what we test here.
SEASTAR_TEST_CASE(test_secondary_index_case_compound_partition_key) {
    return do_with_cql_env_thread([] (auto& e) {
        // Test case-sensitive *table* name.
        e.execute_cql("CREATE TABLE tab (a int, b int, c int, PRIMARY KEY ((a, b)))").get();
        e.execute_cql("CREATE INDEX ON tab (c)").get();
        e.execute_cql("INSERT INTO tab (a, b, c) VALUES (1, 2, 3)").get();
        eventually([&] {
            // We expect this search to find the single row, with the compound
            // partition key (a, b) = (1, 2).
            auto res = e.execute_cql("SELECT * from tab WHERE c = 3").get0();
            assert_that(res).is_rows()
                    .with_size(1)
                    .with_row({
                        {int32_type->decompose(1)},
                        {int32_type->decompose(2)},
                        {int32_type->decompose(3)},
                    });
        });
    });
}

// Tests for issue #2991 - test that "IF NOT EXISTS" works as expected for
// index creation, and "IF EXISTS" for index drop.
SEASTAR_TEST_CASE(test_secondary_index_if_exists) {
    return do_with_cql_env_thread([] (cql_test_env& e) {
        e.execute_cql("create table cf (p int primary key, a int)").get();
        e.execute_cql("create index on cf (a)").get();
        // Confirm that creating the same index again with "if not exists" is
        // fine, but without "if not exists", it's an error.
        e.execute_cql("create index if not exists on cf (a)").get();
        try {
            e.execute_cql("create index on cf (a)").get();
            BOOST_FAIL("Exception expected");
        } catch (exceptions::invalid_request_exception) { }
        // Confirm that after dropping the index, dropping it again with
        // "if exists" is fine, but an error without it.
        e.execute_cql("drop index cf_a_idx").get();
        e.execute_cql("drop index if exists cf_a_idx").get();
        try {
            e.execute_cql("drop index cf_a_idx").get();
            // Expect exceptions::invalid_request_exception: Index 'cf_a_idx'
            // could not be found in any of the tables of keyspace 'ks'
            BOOST_FAIL("Exception expected");
        } catch (exceptions::invalid_request_exception) { }
    });
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef LIBPORT_LOCAL_DATA_HXX
# define LIBPORT_LOCAL_DATA_HXX

# include <boost/type_traits/is_base_of.hpp>
# include <boost/mpl/if.hpp>

namespace libport
{

  namespace localdata
  {
    /// \brief Handle data with only one encapsulation.
    template <typename T>
    struct DataType
    {
      typedef typename T::target target;
      typedef typename T::type type;
      typedef typename T::container container;
      static target* get(container& c, bool create = false);
      static void set(container& c, target* e);
    };

    template <typename T>
    typename DataType<T>::target*
    DataType<T>::get(container& c, bool create)
    {
      return c.get();
    }

    template <typename T>
    void
    DataType<T>::set(container& c, target* e)
    {
      c.reset(e);
    }

    /// \brief Handle data with multiple local data encapsulation.
    template <typename T>
    struct LocalDataType
    {
      typedef typename T::target target;
      typedef typename T::type type;
      typedef typename T::container container;
      static target* get(container& c, bool create = false);
      static void set(container& c, target* e);
    private:
      static type* get_type(container& c, bool create);
    };

    template <typename T>
    typename LocalDataType<T>::type*
    LocalDataType<T>::get_type(container& c, bool create)
    {
      type* e = c.get();

      if (!e)
      {
        if (create)
        {
          e = new type;
          c.reset(e);
        }
        else
          return 0;
      }
      return e;
    }

    template <typename T>
    typename LocalDataType<T>::target*
    LocalDataType<T>::get(container& c, bool create)
    {
      type* e = get_type(c, create);

      if (e)
        return e->get();
      return 0;
    }

    template <typename T>
    void
    LocalDataType<T>::set(container& c, target* e)
    {
      get_type(c, true)->set(e);
    }

    // parametric typedef.
    template <typename T>
    struct WrapperFuns
      : boost::mpl::if_<
          boost::is_base_of<
            AbstractLocalData<typename T::target>,
            typename T::type
          >,
          LocalDataType<T>,
          DataType<T>
        >::type
    {
    };
  }

  template <typename T, typename Enc>
  T*
  LocalData<T, Enc>::get()
  {
    return localdata::WrapperFuns<traits>::get(container_);
  }

  template <typename T, typename Enc>
  void
  LocalData<T, Enc>::set(T* v)
  {
    localdata::WrapperFuns<traits>::set(container_, v);
  }

  template <typename T, typename Enc>
  T&
  LocalSingleton<T, Enc>::instance(builder b)
  {
    T* e = data_.get();
    if (!e)
    {
      assert(!b.empty());
      e = b();
      data_.set(e);
    }
    return *e;
  }
}

#endif
<commit_msg>Libport.LocalData: fix warning.<commit_after>/*
 * Copyright (C) 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef LIBPORT_LOCAL_DATA_HXX
# define LIBPORT_LOCAL_DATA_HXX

# include <boost/type_traits/is_base_of.hpp>
# include <boost/mpl/if.hpp>

namespace libport
{

  namespace localdata
  {
    /// \brief Handle data with only one encapsulation.
    template <typename T>
    struct DataType
    {
      typedef typename T::target target;
      typedef typename T::type type;
      typedef typename T::container container;
      static target* get(container& c, bool create = false);
      static void set(container& c, target* e);
    };

    template <typename T>
    typename DataType<T>::target*
    DataType<T>::get(container& c, bool)
    {
      return c.get();
    }

    template <typename T>
    void
    DataType<T>::set(container& c, target* e)
    {
      c.reset(e);
    }

    /// \brief Handle data with multiple local data encapsulation.
    template <typename T>
    struct LocalDataType
    {
      typedef typename T::target target;
      typedef typename T::type type;
      typedef typename T::container container;
      static target* get(container& c, bool create = false);
      static void set(container& c, target* e);
    private:
      static type* get_type(container& c, bool create);
    };

    template <typename T>
    typename LocalDataType<T>::type*
    LocalDataType<T>::get_type(container& c, bool create)
    {
      type* e = c.get();

      if (!e)
      {
        if (create)
        {
          e = new type;
          c.reset(e);
        }
        else
          return 0;
      }
      return e;
    }

    template <typename T>
    typename LocalDataType<T>::target*
    LocalDataType<T>::get(container& c, bool create)
    {
      type* e = get_type(c, create);

      if (e)
        return e->get();
      return 0;
    }

    template <typename T>
    void
    LocalDataType<T>::set(container& c, target* e)
    {
      get_type(c, true)->set(e);
    }

    // parametric typedef.
    template <typename T>
    struct WrapperFuns
      : boost::mpl::if_<
          boost::is_base_of<
            AbstractLocalData<typename T::target>,
            typename T::type
          >,
          LocalDataType<T>,
          DataType<T>
        >::type
    {
    };
  }

  template <typename T, typename Enc>
  T*
  LocalData<T, Enc>::get()
  {
    return localdata::WrapperFuns<traits>::get(container_);
  }

  template <typename T, typename Enc>
  void
  LocalData<T, Enc>::set(T* v)
  {
    localdata::WrapperFuns<traits>::set(container_, v);
  }

  template <typename T, typename Enc>
  T&
  LocalSingleton<T, Enc>::instance(builder b)
  {
    T* e = data_.get();
    if (!e)
    {
      assert(!b.empty());
      e = b();
      data_.set(e);
    }
    return *e;
  }
}

#endif
<|endoftext|>