<commit_before>/*
Copyright (C) 2009, Eric Sabouraud <eric.sabouraud@gmail.com>
Copyright (C) 2008-2009, Pier Castonguay <dunge2@yahoo.com>

All rights reserved.

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

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

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

#include <stdio.h>
#include <tchar.h>
#include "iig_settings.h"
#include "iig_gui.h"

//* \brief Do not check these processes for game modules
static const TCHAR* defaultBlackList[] = {
	_T("<unknown>"),
	_T("RGSC.EXE"), // rockstar social games club
	_T("WMPLAYER.EXE"),
	_T("ITUNES.EXE"),
	_T("VLC.EXE"), // videolan
	_T("BSPLAYER.EXE"),
	_T("IEXPLORE.EXE"),
	_T("FIREFOX.EXE"),
	_T("OPERA.EXE"),
	_T("WINAMP.EXE"),
	_T("MPLAYERC.EXE"), // media player classic
	_T("EXPLORER.EXE"),
	_T("STEAM.EXE"),
	_T("SMP.EXE"), // steam media player
	_T("msnmsgr.exe"), // msn/live messenger
	_T("nvCplUI.exe"), // nvidia control panel
	_T("mumble.exe"),
	_T("GameOverlayUI.exe") // steam in-game overlay
};

//* \brief Do not check these processes for game modules
static const TCHAR* defaultWhiteList[][2] = {
	{ _T("chuzzle.exe"), _T("Chuzzle") },
	{ _T("WinBej.exe"), _T("Bejeweled") },
};

static int bwListCompare(const void* elt1, const void* elt2) {
	return _tcsicmp(((struct bwListElt*)elt1)->procname, ((struct bwListElt*)elt2)->procname);
}

static int bwListCompareKey(const void* key, const void* elt) {
	return _tcsicmp((TCHAR*)key, ((struct bwListElt*)elt)->procname);
}

struct bwListElt* bwListSearch(const TCHAR* procname, const struct bwListElt list[], int listSize) {
	return (struct bwListElt*)bsearch(procname, list, listSize, sizeof(*list), bwListCompareKey);
}

static void RemoveDoublesFromBWList(struct bwListElt list[], UINT* pListSize) {
	UINT i = 0;
	for (i = 0; *pListSize > 1 && i < *pListSize - 1;) {
		if (_tcsicmp(list[i].procname, list[i+1].procname) == 0) {
			if (i < *pListSize - 2) {
				memmove(&list[i+1], &list[i+2], (*pListSize - (i+2)) * sizeof(*list));
			}
			(*pListSize)--;
		} else {
			++i;
		}
	}
}

void SaveBlackList(const SystemSettings* settings) {
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\blist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		for (i = 0; i < settings->blackListSize; ++i) {
			_ftprintf(file, _T("%s\n"), settings->blackList[i].procname);
		}
		fclose(file);
	}
}

void SaveWhiteList(const SystemSettings* settings) {
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\wlist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		for (i = 0; i < settings->whiteListSize; ++i) {
			_ftprintf(file, _T("%s|%s\n"), settings->whiteList[i].procname, settings->whiteList[i].windowName);
		}
		fclose(file);
	}
}

void LoadWhiteList(SystemSettings* settings) {
	FILE *file = NULL;
	TCHAR filepath[_MAX_PATH];

	// Read whitelist, restore default if missing
	settings->whiteListSize = 0;
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\wlist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		while (settings->whiteListSize < sizeof(settings->whiteList)/sizeof(*settings->whiteList)) {
			if (_ftscanf(file, _T("%255[^|]|%255[^\n]\n"), settings->whiteList[settings->whiteListSize].procname, settings->whiteList[settings->whiteListSize].windowName) == 2) {
				++settings->whiteListSize;
			} else {
				break;
			}
		}
		fclose(file);
	} else {
		while (settings->whiteListSize < sizeof(defaultWhiteList)/sizeof(*defaultWhiteList)
			&& settings->whiteListSize < sizeof(settings->whiteList)/sizeof(*settings->whiteList)) {
			_tcsncpy(settings->whiteList[settings->whiteListSize].procname, defaultWhiteList[settings->whiteListSize][0], 255);
			_tcsncpy(settings->whiteList[settings->whiteListSize].windowName, defaultWhiteList[settings->whiteListSize][1], 255);
			++settings->whiteListSize;
		}
	}
	qsort(settings->whiteList, settings->whiteListSize, sizeof(*settings->whiteList), bwListCompare);
	RemoveDoublesFromBWList(settings->whiteList, &settings->whiteListSize);
}

void LoadBlackList(SystemSettings* settings) {
	FILE *file = NULL;
	TCHAR filepath[_MAX_PATH];

	// Read blacklist, restore default if missing
	settings->blackListSize = 0;
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\blist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		while (settings->blackListSize < sizeof(settings->blackList)/sizeof(*settings->blackList)) {
			if (_ftscanf(file, _T("%255[^\n]\n"), settings->blackList[settings->blackListSize].procname) == 1) {
				++settings->blackListSize;
			} else {
				break;
			}
		}
		fclose(file);
	}

	// Always add default blacklist in order to propagate updates
	while (settings->blackListSize < sizeof(defaultBlackList)/sizeof(*defaultBlackList)
		&& settings->blackListSize < sizeof(settings->blackList)/sizeof(*settings->blackList)) {
		_tcsncpy(settings->blackList[settings->blackListSize].procname, defaultBlackList[settings->blackListSize], 255);
		++settings->blackListSize;
	}

	qsort(settings->blackList, settings->blackListSize, sizeof(*settings->blackList), bwListCompare);
	RemoveDoublesFromBWList(settings->blackList, &settings->blackListSize);
}

static void AddToBWList(struct bwListElt list[], UINT listCapacity, UINT* pListSize, const TCHAR* procname, const TCHAR* windowName) {
	if (*pListSize < listCapacity) {
		_tcscpy(list[*pListSize].procname, procname);
		if (windowName) {
			_tcscpy(list[*pListSize].windowName, windowName);
		}
		++(*pListSize);
		qsort(list, *pListSize, sizeof(*list), bwListCompare);
	}
}

static void RemoveFromBWList(struct bwListElt list[], UINT* pListSize, const TCHAR* procname) {
	struct bwListElt* elt = bwListSearch(procname, list, *pListSize);
	if (elt) {
		int len = &list[*pListSize] - elt;
		if (--len) {
			memmove(elt, elt + 1, len * sizeof(*list));
		}
		--(*pListSize);
	}
}

void AddToBlackList(SystemSettings* settings, const TCHAR* procname) {
	AddToBWList(settings->blackList, sizeof(settings->blackList)/sizeof(*settings->blackList), &settings->blackListSize, procname, NULL);
	SaveBlackList(settings);
}

void RemoveFromBlackList(SystemSettings* settings, const TCHAR* procname) {
	RemoveFromBWList(settings->blackList, &settings->blackListSize, procname);
	SaveBlackList(settings);
}

void AddToWhiteList(SystemSettings* settings, const TCHAR* procname, const TCHAR* windowName) {
	AddToBWList(settings->whiteList, sizeof(settings->whiteList)/sizeof(*settings->whiteList), &settings->whiteListSize, procname, windowName);
	SaveWhiteList(settings);
}

void RemoveFromWhiteList(SystemSettings* settings, const TCHAR* procname) {
	RemoveFromBWList(settings->whiteList, &settings->whiteListSize, procname);
	SaveWhiteList(settings);
}

void SaveSettings(const SystemSettings* settings)
{
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\settings.ini"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		_ftprintf(file, _T("[general]\nuserMessage=%s\ninterval=%u\nasGame=%d\nlegacyTimer=%d\nlang=%u\n"),
			settings->userMessage, settings->interval, settings->asGame, settings->legacyTimer, settings->lang);
		fclose(file);
    }

	SaveWhiteList(settings);
	SaveBlackList(settings);
}

void LoadSettings(SystemSettings* settings)
{
	FILE *file = NULL;
	BOOL loadSuccess = FALSE;
	UINT lang = 0;
	TCHAR filepath[_MAX_PATH];
	DWORD pathlen = sizeof(settings->path);
	HKEY hkey = NULL;

	memset(settings->path, 0, pathlen);

	// Try and read installation directory from registry, use current directory if it fails
	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\IMinGame"), 0, KEY_READ, &hkey)) {
		if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\IMinGame"), 0, KEY_READ, &hkey)) {
			hkey = NULL;
		}
	}

	if (hkey) {
		if (ERROR_SUCCESS != RegQueryValueEx(hkey, _T("Path"), NULL, NULL, (LPBYTE)settings->path, &pathlen)) {
			_sntprintf(settings->path, sizeof(settings->path)/sizeof(*settings->path), _T("."));
		}
		RegCloseKey(hkey);
	}

	// Read settings file if present
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\settings.ini"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		// This part could be replaced with GetPrivateProfileSection/GetPrivateProfileString
		loadSuccess = _ftscanf(file, _T("[general]\nuserMessage=%62[^\n]\ninterval=%u\nasGame=%d\nlegacyTimer=%d\nlang=%u\n"),
			&settings->userMessage, &settings->interval, &settings->asGame, &settings->legacyTimer, &settings->lang) == 5;
		fclose(file);
	}

	// Fallback on pre-settings file (created by installer) if settings file is missing or corrupted
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\presettings.ini"), settings->path);
	if (!loadSuccess && (file = _tfopen(filepath, _T("r"))) != NULL) {
		_ftscanf(file, _T("[general]\nlang=%u\n"), &lang);
		fclose(file);
	}

	// Set default settings
	if (!loadSuccess) {
        settings->interval = 25;
        settings->asGame = FALSE;
		settings->legacyTimer = FALSE;
		settings->lang = lang;
		_tcscpy(settings->userMessage, getLangString(settings->lang, IIG_LANGSTR_USERMSGDEF));
     }

	LoadWhiteList(settings);
	LoadBlackList(settings);
}
<commit_msg>fix current directory not used to store config if registry key not found<commit_after>/*
Copyright (C) 2009, Eric Sabouraud <eric.sabouraud@gmail.com>
Copyright (C) 2008-2009, Pier Castonguay <dunge2@yahoo.com>

All rights reserved.

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

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

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

#include <stdio.h>
#include <tchar.h>
#include "iig_settings.h"
#include "iig_gui.h"

//* \brief Do not check these processes for game modules
static const TCHAR* defaultBlackList[] = {
	_T("<unknown>"),
	_T("RGSC.EXE"), // rockstar social games club
	_T("WMPLAYER.EXE"),
	_T("ITUNES.EXE"),
	_T("VLC.EXE"), // videolan
	_T("BSPLAYER.EXE"),
	_T("IEXPLORE.EXE"),
	_T("FIREFOX.EXE"),
	_T("OPERA.EXE"),
	_T("WINAMP.EXE"),
	_T("MPLAYERC.EXE"), // media player classic
	_T("EXPLORER.EXE"),
	_T("STEAM.EXE"),
	_T("SMP.EXE"), // steam media player
	_T("msnmsgr.exe"), // msn/live messenger
	_T("nvCplUI.exe"), // nvidia control panel
	_T("mumble.exe"),
	_T("GameOverlayUI.exe") // steam in-game overlay
};

//* \brief Do not check these processes for game modules
static const TCHAR* defaultWhiteList[][2] = {
	{ _T("chuzzle.exe"), _T("Chuzzle") },
	{ _T("WinBej.exe"), _T("Bejeweled") },
};

static int bwListCompare(const void* elt1, const void* elt2) {
	return _tcsicmp(((struct bwListElt*)elt1)->procname, ((struct bwListElt*)elt2)->procname);
}

static int bwListCompareKey(const void* key, const void* elt) {
	return _tcsicmp((TCHAR*)key, ((struct bwListElt*)elt)->procname);
}

struct bwListElt* bwListSearch(const TCHAR* procname, const struct bwListElt list[], int listSize) {
	return (struct bwListElt*)bsearch(procname, list, listSize, sizeof(*list), bwListCompareKey);
}

static void RemoveDoublesFromBWList(struct bwListElt list[], UINT* pListSize) {
	UINT i = 0;
	for (i = 0; *pListSize > 1 && i < *pListSize - 1;) {
		if (_tcsicmp(list[i].procname, list[i+1].procname) == 0) {
			if (i < *pListSize - 2) {
				memmove(&list[i+1], &list[i+2], (*pListSize - (i+2)) * sizeof(*list));
			}
			(*pListSize)--;
		} else {
			++i;
		}
	}
}

void SaveBlackList(const SystemSettings* settings) {
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\blist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		for (i = 0; i < settings->blackListSize; ++i) {
			_ftprintf(file, _T("%s\n"), settings->blackList[i].procname);
		}
		fclose(file);
	}
}

void SaveWhiteList(const SystemSettings* settings) {
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\wlist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		for (i = 0; i < settings->whiteListSize; ++i) {
			_ftprintf(file, _T("%s|%s\n"), settings->whiteList[i].procname, settings->whiteList[i].windowName);
		}
		fclose(file);
	}
}

void LoadWhiteList(SystemSettings* settings) {
	FILE *file = NULL;
	TCHAR filepath[_MAX_PATH];

	// Read whitelist, restore default if missing
	settings->whiteListSize = 0;
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\wlist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		while (settings->whiteListSize < sizeof(settings->whiteList)/sizeof(*settings->whiteList)) {
			if (_ftscanf(file, _T("%255[^|]|%255[^\n]\n"), settings->whiteList[settings->whiteListSize].procname, settings->whiteList[settings->whiteListSize].windowName) == 2) {
				++settings->whiteListSize;
			} else {
				break;
			}
		}
		fclose(file);
	} else {
		while (settings->whiteListSize < sizeof(defaultWhiteList)/sizeof(*defaultWhiteList)
			&& settings->whiteListSize < sizeof(settings->whiteList)/sizeof(*settings->whiteList)) {
			_tcsncpy(settings->whiteList[settings->whiteListSize].procname, defaultWhiteList[settings->whiteListSize][0], 255);
			_tcsncpy(settings->whiteList[settings->whiteListSize].windowName, defaultWhiteList[settings->whiteListSize][1], 255);
			++settings->whiteListSize;
		}
	}
	qsort(settings->whiteList, settings->whiteListSize, sizeof(*settings->whiteList), bwListCompare);
	RemoveDoublesFromBWList(settings->whiteList, &settings->whiteListSize);
}

void LoadBlackList(SystemSettings* settings) {
	FILE *file = NULL;
	TCHAR filepath[_MAX_PATH];

	// Read blacklist, restore default if missing
	settings->blackListSize = 0;
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\blist.txt"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		while (settings->blackListSize < sizeof(settings->blackList)/sizeof(*settings->blackList)) {
			if (_ftscanf(file, _T("%255[^\n]\n"), settings->blackList[settings->blackListSize].procname) == 1) {
				++settings->blackListSize;
			} else {
				break;
			}
		}
		fclose(file);
	}

	// Always add default blacklist in order to propagate updates
	while (settings->blackListSize < sizeof(defaultBlackList)/sizeof(*defaultBlackList)
		&& settings->blackListSize < sizeof(settings->blackList)/sizeof(*settings->blackList)) {
		_tcsncpy(settings->blackList[settings->blackListSize].procname, defaultBlackList[settings->blackListSize], 255);
		++settings->blackListSize;
	}

	qsort(settings->blackList, settings->blackListSize, sizeof(*settings->blackList), bwListCompare);
	RemoveDoublesFromBWList(settings->blackList, &settings->blackListSize);
}

static void AddToBWList(struct bwListElt list[], UINT listCapacity, UINT* pListSize, const TCHAR* procname, const TCHAR* windowName) {
	if (*pListSize < listCapacity) {
		_tcscpy(list[*pListSize].procname, procname);
		if (windowName) {
			_tcscpy(list[*pListSize].windowName, windowName);
		}
		++(*pListSize);
		qsort(list, *pListSize, sizeof(*list), bwListCompare);
	}
}

static void RemoveFromBWList(struct bwListElt list[], UINT* pListSize, const TCHAR* procname) {
	struct bwListElt* elt = bwListSearch(procname, list, *pListSize);
	if (elt) {
		int len = &list[*pListSize] - elt;
		if (--len) {
			memmove(elt, elt + 1, len * sizeof(*list));
		}
		--(*pListSize);
	}
}

void AddToBlackList(SystemSettings* settings, const TCHAR* procname) {
	AddToBWList(settings->blackList, sizeof(settings->blackList)/sizeof(*settings->blackList), &settings->blackListSize, procname, NULL);
	SaveBlackList(settings);
}

void RemoveFromBlackList(SystemSettings* settings, const TCHAR* procname) {
	RemoveFromBWList(settings->blackList, &settings->blackListSize, procname);
	SaveBlackList(settings);
}

void AddToWhiteList(SystemSettings* settings, const TCHAR* procname, const TCHAR* windowName) {
	AddToBWList(settings->whiteList, sizeof(settings->whiteList)/sizeof(*settings->whiteList), &settings->whiteListSize, procname, windowName);
	SaveWhiteList(settings);
}

void RemoveFromWhiteList(SystemSettings* settings, const TCHAR* procname) {
	RemoveFromBWList(settings->whiteList, &settings->whiteListSize, procname);
	SaveWhiteList(settings);
}

void SaveSettings(const SystemSettings* settings)
{
	FILE *file = NULL;
	UINT i = 0;
	TCHAR filepath[_MAX_PATH];

	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\settings.ini"), settings->path);
	if ((file = _tfopen(filepath, _T("w"))) != NULL) {
		_ftprintf(file, _T("[general]\nuserMessage=%s\ninterval=%u\nasGame=%d\nlegacyTimer=%d\nlang=%u\n"),
			settings->userMessage, settings->interval, settings->asGame, settings->legacyTimer, settings->lang);
		fclose(file);
    }

	SaveWhiteList(settings);
	SaveBlackList(settings);
}

void LoadSettings(SystemSettings* settings)
{
	FILE *file = NULL;
	BOOL loadSuccess = FALSE;
	UINT lang = 0;
	TCHAR filepath[_MAX_PATH];
	DWORD pathlen = sizeof(settings->path);
	HKEY hkey = NULL;

	memset(settings->path, 0, pathlen);
	_sntprintf(settings->path, sizeof(settings->path)/sizeof(*settings->path), _T("."));

	// Try and read installation directory from registry, use current directory if it fails
	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\IMinGame"), 0, KEY_READ, &hkey)) {
		if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\IMinGame"), 0, KEY_READ, &hkey)) {
			hkey = NULL;
		}
	}

	if (hkey) {
		if (ERROR_SUCCESS != RegQueryValueEx(hkey, _T("Path"), NULL, NULL, (LPBYTE)settings->path, &pathlen)) {
			_sntprintf(settings->path, sizeof(settings->path)/sizeof(*settings->path), _T("."));
		}
		RegCloseKey(hkey);
	}

	// Read settings file if present
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\settings.ini"), settings->path);
	if ((file = _tfopen(filepath, _T("r"))) != NULL) {
		// This part could be replaced with GetPrivateProfileSection/GetPrivateProfileString
		loadSuccess = _ftscanf(file, _T("[general]\nuserMessage=%62[^\n]\ninterval=%u\nasGame=%d\nlegacyTimer=%d\nlang=%u\n"),
			&settings->userMessage, &settings->interval, &settings->asGame, &settings->legacyTimer, &settings->lang) == 5;
		fclose(file);
	}

	// Fallback on pre-settings file (created by installer) if settings file is missing or corrupted
	_sntprintf(filepath, sizeof(filepath)/sizeof(*filepath), _T("%s\\presettings.ini"), settings->path);
	if (!loadSuccess && (file = _tfopen(filepath, _T("r"))) != NULL) {
		_ftscanf(file, _T("[general]\nlang=%u\n"), &lang);
		fclose(file);
	}

	// Set default settings
	if (!loadSuccess) {
        settings->interval = 25;
        settings->asGame = FALSE;
		settings->legacyTimer = FALSE;
		settings->lang = lang;
		_tcscpy(settings->userMessage, getLangString(settings->lang, IIG_LANGSTR_USERMSGDEF));
     }

	LoadWhiteList(settings);
	LoadBlackList(settings);
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestMetaIO.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME Test of vtkMetaIO / MetaImage
// .SECTION Description
//

#include "vtkMetaImageReader.h"
#include "vtkMetaImageWriter.h"
#include "vtkOutputWindow.h"
#include "vtkObjectFactory.h"
#include "vtkDataObject.h"
#include "vtkImageData.h"
#include "vtkImageMathematics.h"

int TestMetaIO(int argc, char *argv[])
{
  vtkOutputWindow::GetInstance()->PromptUserOn();
  if ( argc <= 1 )
    {
    cout << "Usage: " << argv[0] << " <xml file>" << endl;
    return 1;
    }

  vtkMetaImageReader *reader = vtkMetaImageReader::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  cout << "10, 10, 10 : (1) : "
       << reader->GetOutput()->GetScalarComponentAsFloat(10, 10, 10, 0)
       << endl;
  cout << "24, 37, 10 : (168) : "
       << reader->GetOutput()->GetScalarComponentAsFloat(24, 37, 10, 0)
       << endl;

  vtkMetaImageWriter *writer = vtkMetaImageWriter::New();
  writer->SetFileName("TestMetaIO.mha");
  writer->SetInputConnection(reader->GetOutputPort());
  writer->Write();

  reader->Delete();
  writer->Delete();

  vtkMetaImageReader *readerStd = vtkMetaImageReader::New();
  readerStd->SetFileName(argv[1]);
  readerStd->Update();

  vtkMetaImageReader *readerNew = vtkMetaImageReader::New();
  readerNew->SetFileName("TestMetaIO.mha");
  readerNew->Update();

  double error = 0;
  int * ext = readerStd->GetOutput()->GetWholeExtent();
  for(int z=ext[4]; z<=ext[5]; z++)
    {
    for(int y=ext[2]; y<=ext[3]; y++)
      {
      for(int x=ext[0]; x<=ext[1]; x++)
        {
        error += fabs(
                  readerStd->GetOutput()->GetScalarComponentAsFloat(x, y, z, 0)
                  -
                  readerNew->GetOutput()->GetScalarComponentAsFloat(x, y, z, 0)
                  );
        }
      }
    }

  if(error > 1)
    {
    cerr << "Error: Image difference on read/write = " << error << endl;
    return 1;
    }

  cout << "Success!  Error = " << error << endl;

  return 0;
}
<commit_msg>BUG: fixing leaks<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestMetaIO.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME Test of vtkMetaIO / MetaImage
// .SECTION Description
//

#include "vtkMetaImageReader.h"
#include "vtkMetaImageWriter.h"
#include "vtkOutputWindow.h"
#include "vtkObjectFactory.h"
#include "vtkDataObject.h"
#include "vtkImageData.h"
#include "vtkImageMathematics.h"

int TestMetaIO(int argc, char *argv[])
{
  vtkOutputWindow::GetInstance()->PromptUserOn();
  if ( argc <= 1 )
    {
    cout << "Usage: " << argv[0] << " <xml file>" << endl;
    return 1;
    }

  vtkMetaImageReader *reader = vtkMetaImageReader::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  cout << "10, 10, 10 : (1) : "
       << reader->GetOutput()->GetScalarComponentAsFloat(10, 10, 10, 0)
       << endl;
  cout << "24, 37, 10 : (168) : "
       << reader->GetOutput()->GetScalarComponentAsFloat(24, 37, 10, 0)
       << endl;

  vtkMetaImageWriter *writer = vtkMetaImageWriter::New();
  writer->SetFileName("TestMetaIO.mha");
  writer->SetInputConnection(reader->GetOutputPort());
  writer->Write();

  reader->Delete();
  writer->Delete();

  vtkMetaImageReader *readerStd = vtkMetaImageReader::New();
  readerStd->SetFileName(argv[1]);
  readerStd->Update();

  vtkMetaImageReader *readerNew = vtkMetaImageReader::New();
  readerNew->SetFileName("TestMetaIO.mha");
  readerNew->Update();

  double error = 0;
  int * ext = readerStd->GetOutput()->GetWholeExtent();
  for(int z=ext[4]; z<=ext[5]; z++)
    {
    for(int y=ext[2]; y<=ext[3]; y++)
      {
      for(int x=ext[0]; x<=ext[1]; x++)
        {
        error += fabs(
                  readerStd->GetOutput()->GetScalarComponentAsFloat(x, y, z, 0)
                  -
                  readerNew->GetOutput()->GetScalarComponentAsFloat(x, y, z, 0)
                  );
        }
      }
    }

  readerStd->Delete();
  readerNew->Delete();

  if(error > 1)
    {
    cerr << "Error: Image difference on read/write = " << error << endl;
    return 1;
    }

  cout << "Success!  Error = " << error << endl;

  return 0;
}
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "itkRescaleIntensityImageFilter.h"
#include "otbVectorRescaleIntensityImageFilter.h"

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROI_QB_MUL_1.png}
//    OUTPUTS: {PCAOutput.tif}, {InversePCAOutput.tif}, {InversePCAOutput1.png}, {PCAOutput1.png}, {PCAOutput2.png}, {PCAOutput3.png}
//    3
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example illustrates the use of the
// \doxygen{otb}{PCAImageFilter}.
// This filter computes a Principal Component Analysis using an
// efficient method based on the inner product in order to compute the
// covariance matrix.
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbPCAImageFilter.h"
// Software Guide : EndCodeSnippet

int main(int argc, char* argv[])
{
  typedef double PixelType;
  const unsigned int Dimension = 2;
  const char *       inputFileName = argv[1];
  const char *       outputFilename = argv[2];
  const char *       outputInverseFilename = argv[3];
  const unsigned int numberOfPrincipalComponentsRequired(atoi(argv[8]));

  // Software Guide : BeginLatex
  //
  // We start by defining the types for the images and the reader and
  // the writer. We choose to work with a \doxygen{otb}{VectorImage},
  // since we will produce a multi-channel image (the principal
  // components) from a multi-channel input image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::VectorImage<PixelType, Dimension> ImageType;
  typedef otb::ImageFileReader<ImageType>        ReaderType;
  typedef otb::ImageFileWriter<ImageType>        WriterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We instantiate now the image reader and we set the image file name.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ReaderType::Pointer reader     = ReaderType::New();
  reader->SetFileName(inputFileName);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We define the type for the filter. It is templated over the input
  // and the output image types and also the transformation direction. The
  // internal structure of this filter is a filter-to-filter like structure.
  // We can now the instantiate the filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::PCAImageFilter<ImageType, ImageType,
                              otb::Transform::FORWARD> PCAFilterType;
  PCAFilterType::Pointer pcafilter     = PCAFilterType::New();
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The only parameter needed for the PCA is the number of principal
  // components required as output. We can choose to get less PCs than
  // the number of input bands.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  pcafilter->SetNumberOfPrincipalComponentsRequired(
    numberOfPrincipalComponentsRequired);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We now instantiate the writer and set the file name for the
  // output image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  WriterType::Pointer writer     = WriterType::New();
  writer->SetFileName(outputFilename);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We finally plug the pipeline and trigger the PCA computation with
  // the method \code{Update()} of the writer.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  pcafilter->SetInput(reader->GetOutput());
  writer->SetInput(pcafilter->GetOutput());

  writer->Update();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // \doxygen{otb}{PCAImageFilter} allows also to compute inverse
  // transformation from PCA coefficients. In REVERSE mode, the
  // covariance matrix or the transformation matrix
  // (which may not be square) has to be given.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::PCAImageFilter< ImageType, ImageType, otb::Transform::INVERSE > InvPCAFilterType;
  InvPCAFilterType::Pointer invFilter = InvPCAFilterType::New();
  invFilter->SetInput(pcafilter->GetOutput());
  invFilter->SetTransformationMatrix(pcafilter->GetTransformationMatrix());

  WriterType::Pointer invWriter = WriterType::New();
  invWriter->SetFileName(outputInverseFilename );
  invWriter->SetInput(invFilter->GetOutput() );

  invWriter->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  // Figure~\ref{fig:PCA_FILTER} shows the result of applying
  // the PCA to a 3 band RGB image.
  // \begin{figure}
  // \center
  // \includegraphics[width=0.25\textwidth]{ROI_QB_MUL_1.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput1.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput2.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput3.eps}
  // \includegraphics[width=0.25\textwidth]{InversePCAOutput1.eps}
  // \itkcaption[PCA Filter (forward trasnformation)]{Result of applying the
  // \doxygen{otb}{PCAImageFilter} to an image. From left
  // to right and top to bottom:
  // original image, first PC, second PC, third PC and inverse mode output.}
  // \label{fig:PCA_FILTER}
  // \end{figure}
  //
  //  Software Guide : EndLatex

  typedef otb::Image<PixelType, Dimension> MonoImageType;

  typedef otb::MultiToMonoChannelExtractROI<PixelType, PixelType>
  ExtractROIFilterType;

  typedef otb::Image<unsigned char, 2>                OutputImageType;
  typedef otb::VectorImage<unsigned char, 2>          OutputPrettyImageType;
  typedef otb::ImageFileWriter<OutputImageType>       WriterType2;
  typedef otb::ImageFileWriter<OutputPrettyImageType> WriterType3;

  typedef itk::RescaleIntensityImageFilter<MonoImageType,
                                           OutputImageType> RescalerType;

  typedef otb::VectorRescaleIntensityImageFilter<ImageType,
                                                 OutputPrettyImageType> RescalerType2;

  typedef ImageType::PixelType                  VectorPixelType;

  for (unsigned int cpt = 0; cpt < numberOfPrincipalComponentsRequired; cpt++)
    {
    ExtractROIFilterType::Pointer extractROIFilter = ExtractROIFilterType::New();
    RescalerType::Pointer         rescaler = RescalerType::New();
    WriterType2::Pointer          writer2 = WriterType2::New();

    extractROIFilter->SetInput(pcafilter->GetOutput());
    extractROIFilter->SetChannel(cpt + 1);

    rescaler->SetInput(extractROIFilter->GetOutput());
    rescaler->SetOutputMinimum(0);
    rescaler->SetOutputMaximum(255);

    writer2->SetInput(rescaler->GetOutput());
    writer2->SetFileName(argv[cpt + 5]);
    writer2->Update();
    }

  WriterType3::Pointer          writerInverse = WriterType3::New();
  RescalerType2::Pointer        rescalerInverse = RescalerType2::New();
  rescalerInverse->SetInput(invFilter->GetOutput());

  VectorPixelType minimum, maximum;
  minimum.SetSize(3);
  maximum.SetSize(3);
  minimum.Fill(0);
  maximum.Fill(255);
  rescalerInverse->SetOutputMinimum(minimum);
  rescalerInverse->SetOutputMaximum(maximum);

  writerInverse->SetInput(rescalerInverse->GetOutput());
  writerInverse->SetFileName(argv[4]);
  writerInverse->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH:minor modifications of pca example<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "itkRescaleIntensityImageFilter.h"
#include "otbVectorRescaleIntensityImageFilter.h"

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROI_QB_MUL_1.png}
//    OUTPUTS: {PCAOutput.tif}, {InversePCAOutput.tif}, {InversePCAOutput1.png}, {PCAOutput1.png}, {PCAOutput2.png}, {PCAOutput3.png}
//    3
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example illustrates the use of the
// \doxygen{otb}{PCAImageFilter}.
// This filter computes a Principal Component Analysis using an
// efficient method based on the inner product in order to compute the
// covariance matrix.
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbPCAImageFilter.h"
// Software Guide : EndCodeSnippet

int main(int argc, char* argv[])
{
  typedef double PixelType;
  const unsigned int Dimension = 2;
  const char *       inputFileName = argv[1];
  const char *       outputFilename = argv[2];
  const char *       outputInverseFilename = argv[3];
  const unsigned int numberOfPrincipalComponentsRequired(atoi(argv[8]));

  // Software Guide : BeginLatex
  //
  // We start by defining the types for the images and the reader and
  // the writer. We choose to work with a \doxygen{otb}{VectorImage},
  // since we will produce a multi-channel image (the principal
  // components) from a multi-channel input image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::VectorImage<PixelType, Dimension> ImageType;
  typedef otb::ImageFileReader<ImageType>        ReaderType;
  typedef otb::ImageFileWriter<ImageType>        WriterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We instantiate now the image reader and we set the image file name.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ReaderType::Pointer reader     = ReaderType::New();
  reader->SetFileName(inputFileName);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We define the type for the filter. It is templated over the input
  // and the output image types and also the transformation direction. The
  // internal structure of this filter is a filter-to-filter like structure.
  // We can now the instantiate the filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::PCAImageFilter<ImageType, ImageType,
                              otb::Transform::FORWARD> PCAFilterType;
  PCAFilterType::Pointer pcafilter     = PCAFilterType::New();
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The only parameter needed for the PCA is the number of principal
  // components required as output. We can choose to get less PCs than
  // the number of input bands.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  pcafilter->SetNumberOfPrincipalComponentsRequired(
    numberOfPrincipalComponentsRequired);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We now instantiate the writer and set the file name for the
  // output image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  WriterType::Pointer writer     = WriterType::New();
  writer->SetFileName(outputFilename);
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We finally plug the pipeline and trigger the PCA computation with
  // the method \code{Update()} of the writer.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  pcafilter->SetInput(reader->GetOutput());
  writer->SetInput(pcafilter->GetOutput());

  writer->Update();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // \doxygen{otb}{PCAImageFilter} allows also to compute inverse
  // transformation from PCA coefficients. In reverse mode, the
  // covariance matrix or the transformation matrix
  // (which may not be square) has to be given.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::PCAImageFilter< ImageType, ImageType,
			       otb::Transform::INVERSE > InvPCAFilterType;
  InvPCAFilterType::Pointer invFilter = InvPCAFilterType::New();

  invFilter->SetInput(pcafilter->GetOutput());
  invFilter->SetTransformationMatrix(pcafilter->GetTransformationMatrix());

  WriterType::Pointer invWriter = WriterType::New();
  invWriter->SetFileName(outputInverseFilename );
  invWriter->SetInput(invFilter->GetOutput() );

  invWriter->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  // Figure~\ref{fig:PCA_FILTER} shows the result of applying forward
  // and reverse PCA transformation to a 3 band RGB image.
  // \begin{figure}
  // \center
  // \includegraphics[width=0.25\textwidth]{ROI_QB_MUL_1.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput1.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput2.eps}
  // \includegraphics[width=0.25\textwidth]{PCAOutput3.eps}
  // \includegraphics[width=0.25\textwidth]{InversePCAOutput1.eps}
  // \itkcaption[PCA Filter (forward trasnformation)]{Result of applying the
  // \doxygen{otb}{PCAImageFilter} to an image. From left
  // to right and top to bottom:
  // original image, first PC, second PC, third PC and output of the
  // inverse mode (the input RGB image).}
  // \label{fig:PCA_FILTER}
  // \end{figure}
  //
  //  Software Guide : EndLatex

  typedef otb::Image<PixelType, Dimension> MonoImageType;

  typedef otb::MultiToMonoChannelExtractROI<PixelType, PixelType>
  ExtractROIFilterType;

  typedef otb::Image<unsigned char, 2>                OutputImageType;
  typedef otb::VectorImage<unsigned char, 2>          OutputPrettyImageType;
  typedef otb::ImageFileWriter<OutputImageType>       WriterType2;
  typedef otb::ImageFileWriter<OutputPrettyImageType> WriterType3;

  typedef itk::RescaleIntensityImageFilter<MonoImageType,
                                           OutputImageType> RescalerType;

  typedef otb::VectorRescaleIntensityImageFilter<ImageType,
                                                 OutputPrettyImageType> RescalerType2;

  typedef ImageType::PixelType                  VectorPixelType;

  for (unsigned int cpt = 0; cpt < numberOfPrincipalComponentsRequired; cpt++)
    {
    ExtractROIFilterType::Pointer extractROIFilter = ExtractROIFilterType::New();
    RescalerType::Pointer         rescaler = RescalerType::New();
    WriterType2::Pointer          writer2 = WriterType2::New();

    extractROIFilter->SetInput(pcafilter->GetOutput());
    extractROIFilter->SetChannel(cpt + 1);

    rescaler->SetInput(extractROIFilter->GetOutput());
    rescaler->SetOutputMinimum(0);
    rescaler->SetOutputMaximum(255);

    writer2->SetInput(rescaler->GetOutput());
    writer2->SetFileName(argv[cpt + 5]);
    writer2->Update();
    }

  WriterType3::Pointer          writerInverse = WriterType3::New();
  RescalerType2::Pointer        rescalerInverse = RescalerType2::New();
  rescalerInverse->SetInput(invFilter->GetOutput());

  VectorPixelType minimum, maximum;
  minimum.SetSize(3);
  maximum.SetSize(3);
  minimum.Fill(0);
  maximum.Fill(255);
  rescalerInverse->SetOutputMinimum(minimum);
  rescalerInverse->SetOutputMaximum(maximum);

  writerInverse->SetInput(rescalerInverse->GetOutput());
  writerInverse->SetFileName(argv[4]);
  writerInverse->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    FourierDescriptors1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

//  Software Guide : BeginLatex
//
//  Fourier Descriptors provide a mechanism for representing a closed curve in
//  space.  The represented curve has infinite continuiity because the
//  parametric coordinate of its points are computed from a Fourier Series.
//
//  In this example we illustrate how a curve that is initially defined by a
//  set of points in space can be represented in terms for Fourier Descriptors.
//  This representation is useful for several purposes. For example, it
//  provides a mechanmism for interpolating values among the points, it
//  provides a way of analyzing the smoothness of the curve.  In this particular
//  example we will focus on this second application of the Fourier Descriptors.
//
//  The first operation that we should use in this context is the computation
//  of the discrete fourier transform of the point coordinates. The coordinates
//  of the points are considered to be independent functions and each one is
//  decomposed in a Fourier Series. In this section we will use $t$ as the
//  parameter of the curve, and will assume that it goes from $0$ to $1$ and
//  cycles as we go around the closed curve. //
//  \begin{equation}
//  \textbf{V(t)} = \left( X(t), Y(t) \rigth)
//  \end{equation}
//
//  We take now the functions $X(t)$, $Y(t)$ and interpret them as the
//  components of a complex number for wich we compute its discrete fourier
//  series in the form
//
//  \begin{equation}
//  V(t) = \sum_{k=0}^{N} \exp(-\frac{2 k \pi \textbf{i}}{N}) F_k
//  \end{equation}
//
//  Where the set of coefficients $F_k$ is the discrete spectrum of the complex
//  function $V(t)$. These coefficients are in general complex numbers and both
//  their magnitude and phase must be considered in any further analysis of the
//  spectrum.
//
//  Software Guide : EndLatex

//  Software Guide : BeginLatex
//
//  The class \code{vnl_fft_1D} is the VNL class that computes such transform.
//  In order to use it, we should include its header file first.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "vnl/algo/vnl_fft_1d.h"
// Software Guide : EndCodeSnippet

#include "itkPoint.h"
#include "itkVectorContainer.h"

#include <fstream>

int main(int argc, char * argv[] )
{

  if( argc < 2 )
    {
    std::cerr << "Missing arguments" << std::endl;
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "inputFileWithPointCoordinates" << std::endl;
    return EXIT_FAILURE;
    }

  //  Software Guide : BeginLatex
  //
  //  We should now instantiate the filter that will compute the Fourier
  //  transform of the set of coordinates.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef vnl_fft_1d< double > FFTCalculator;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The points representing the curve are stored in a
  //  \doxygen{VectorContainer} of \doxygen{Point}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Point< double, 2 >  PointType;

  typedef itk::VectorContainer< unsigned int, PointType >  PointsContainer;

  PointsContainer::Pointer points = PointsContainer::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  In this example we read the set of points from a text file.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::ifstream inputFile;
  inputFile.open( argv[1] );

  if( inputFile.fail() )
    {
    std::cerr << "Problems opening file " << argv[1] << std::endl;
    }

  unsigned int numberOfPoints;
  inputFile >> numberOfPoints;

  points->Reserve( numberOfPoints );

  typedef PointsContainer::Iterator PointIterator;
  PointIterator pointItr = points->Begin();

  PointType point;
  for( unsigned int pt=0; pt<numberOfPoints; pt++)
    {
    inputFile >> point[0] >> point[1];
    pointItr.Value() = point;
    ++pointItr;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  This class will compute the Fast Fourier transform of the input an it will
  //  return it in the same array. We must therefore copy the original data into
  //  an auxiliary array that will in its turn contain the results of the
  //  transform.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef vcl_complex<double>   FFTCoefficientType;
  typedef vcl_vector< FFTCoefficientType > FFTSpectrumType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // The choice of the spectrum size is very important. Here we select to use
  // the next power of two that is larger than the number of points.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const unsigned int powerOfTwo   = (unsigned int)ceil( log( (double)(numberOfPoints)) /
                                          log( (double)(2.0)));

  const unsigned int spectrumSize = 1 << powerOfTwo;

  //  Software Guide : BeginLatex
  //
  //  The Fourier Transform type can now be used for constructing one of such
  //  filters. Note that this is a VNL class and does not follows ITK notation
  //  for construction and assignment to SmartPointers.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  FFTCalculator  fftCalculator( spectrumSize );
  // Software Guide : EndCodeSnippet

  FFTSpectrumType signal( spectrumSize );

  pointItr = points->Begin();
  for(unsigned int p=0; p<numberOfPoints; p++)
    {
    signal[p] = FFTCoefficientType( pointItr.Value()[0], pointItr.Value()[1] );
    ++pointItr;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Fill in the rest of the input with zeros. This padding may have
  // undesirable effects on the spectrum if the signal is not attenuated to
  // zero close to their boundaries. Instead of zero-padding we could have used
  // repetition of the last value or mirroring of the signal.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  for(unsigned int pad=numberOfPoints; pad<spectrumSize; pad++)
    {
    signal[pad] = 0.0;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now we print out the signal as it is passed to the transform calculator
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::cout << "Input to the FFT transform" << std::endl;
  for(unsigned int s=0; s<spectrumSize; s++)
    {
    std::cout << s << " : ";
    std::cout << signal[s] << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The actual transform is computed by invoking the \code{fwd_transform}
  //  method in the FFT calculator class.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  fftCalculator.fwd_transform( signal );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now we print out the results of the transform.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::cout << std::endl;
  std::cout << "Result from the FFT transform" << std::endl;
  for(unsigned int k=0; k<spectrumSize; k++)
    {
    const double real = signal[k].real();
    const double imag = signal[k].imag();
    const double magnitude = vcl_sqrt( real * real + imag * imag );
    std::cout << k << "  " << magnitude << std::endl;
    }
  // Software Guide : EndCodeSnippet

  return EXIT_SUCCESS;
}

<commit_msg>COMP: Replacing "log" and "ceil" with "vcl_log" and "vcl_ceil" in order to support Sun-CC with -stlport4.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    FourierDescriptors1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

//  Software Guide : BeginLatex
//
//  Fourier Descriptors provide a mechanism for representing a closed curve in
//  space.  The represented curve has infinite continuiity because the
//  parametric coordinate of its points are computed from a Fourier Series.
//
//  In this example we illustrate how a curve that is initially defined by a
//  set of points in space can be represented in terms for Fourier Descriptors.
//  This representation is useful for several purposes. For example, it
//  provides a mechanmism for interpolating values among the points, it
//  provides a way of analyzing the smoothness of the curve.  In this particular
//  example we will focus on this second application of the Fourier Descriptors.
//
//  The first operation that we should use in this context is the computation
//  of the discrete fourier transform of the point coordinates. The coordinates
//  of the points are considered to be independent functions and each one is
//  decomposed in a Fourier Series. In this section we will use $t$ as the
//  parameter of the curve, and will assume that it goes from $0$ to $1$ and
//  cycles as we go around the closed curve. //
//  \begin{equation}
//  \textbf{V(t)} = \left( X(t), Y(t) \rigth)
//  \end{equation}
//
//  We take now the functions $X(t)$, $Y(t)$ and interpret them as the
//  components of a complex number for wich we compute its discrete fourier
//  series in the form
//
//  \begin{equation}
//  V(t) = \sum_{k=0}^{N} \exp(-\frac{2 k \pi \textbf{i}}{N}) F_k
//  \end{equation}
//
//  Where the set of coefficients $F_k$ is the discrete spectrum of the complex
//  function $V(t)$. These coefficients are in general complex numbers and both
//  their magnitude and phase must be considered in any further analysis of the
//  spectrum.
//
//  Software Guide : EndLatex

//  Software Guide : BeginLatex
//
//  The class \code{vnl_fft_1D} is the VNL class that computes such transform.
//  In order to use it, we should include its header file first.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "vnl/algo/vnl_fft_1d.h"
// Software Guide : EndCodeSnippet

#include "itkPoint.h"
#include "itkVectorContainer.h"

#include <fstream>

int main(int argc, char * argv[] )
{

  if( argc < 2 )
    {
    std::cerr << "Missing arguments" << std::endl;
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "inputFileWithPointCoordinates" << std::endl;
    return EXIT_FAILURE;
    }

  //  Software Guide : BeginLatex
  //
  //  We should now instantiate the filter that will compute the Fourier
  //  transform of the set of coordinates.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef vnl_fft_1d< double > FFTCalculator;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The points representing the curve are stored in a
  //  \doxygen{VectorContainer} of \doxygen{Point}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::Point< double, 2 >  PointType;

  typedef itk::VectorContainer< unsigned int, PointType >  PointsContainer;

  PointsContainer::Pointer points = PointsContainer::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  In this example we read the set of points from a text file.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::ifstream inputFile;
  inputFile.open( argv[1] );

  if( inputFile.fail() )
    {
    std::cerr << "Problems opening file " << argv[1] << std::endl;
    }

  unsigned int numberOfPoints;
  inputFile >> numberOfPoints;

  points->Reserve( numberOfPoints );

  typedef PointsContainer::Iterator PointIterator;
  PointIterator pointItr = points->Begin();

  PointType point;
  for( unsigned int pt=0; pt<numberOfPoints; pt++)
    {
    inputFile >> point[0] >> point[1];
    pointItr.Value() = point;
    ++pointItr;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  This class will compute the Fast Fourier transform of the input an it will
  //  return it in the same array. We must therefore copy the original data into
  //  an auxiliary array that will in its turn contain the results of the
  //  transform.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef vcl_complex<double>   FFTCoefficientType;
  typedef vcl_vector< FFTCoefficientType > FFTSpectrumType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // The choice of the spectrum size is very important. Here we select to use
  // the next power of two that is larger than the number of points.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const unsigned int powerOfTwo   =
    (unsigned int)vcl_ceil( vcl_log( (double)(numberOfPoints)) /
                            vcl_log( (double)(2.0)) );

  const unsigned int spectrumSize = 1 << powerOfTwo;

  //  Software Guide : BeginLatex
  //
  //  The Fourier Transform type can now be used for constructing one of such
  //  filters. Note that this is a VNL class and does not follows ITK notation
  //  for construction and assignment to SmartPointers.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  FFTCalculator  fftCalculator( spectrumSize );
  // Software Guide : EndCodeSnippet

  FFTSpectrumType signal( spectrumSize );

  pointItr = points->Begin();
  for(unsigned int p=0; p<numberOfPoints; p++)
    {
    signal[p] = FFTCoefficientType( pointItr.Value()[0], pointItr.Value()[1] );
    ++pointItr;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Fill in the rest of the input with zeros. This padding may have
  // undesirable effects on the spectrum if the signal is not attenuated to
  // zero close to their boundaries. Instead of zero-padding we could have used
  // repetition of the last value or mirroring of the signal.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  for(unsigned int pad=numberOfPoints; pad<spectrumSize; pad++)
    {
    signal[pad] = 0.0;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now we print out the signal as it is passed to the transform calculator
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::cout << "Input to the FFT transform" << std::endl;
  for(unsigned int s=0; s<spectrumSize; s++)
    {
    std::cout << s << " : ";
    std::cout << signal[s] << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The actual transform is computed by invoking the \code{fwd_transform}
  //  method in the FFT calculator class.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  fftCalculator.fwd_transform( signal );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now we print out the results of the transform.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::cout << std::endl;
  std::cout << "Result from the FFT transform" << std::endl;
  for(unsigned int k=0; k<spectrumSize; k++)
    {
    const double real = signal[k].real();
    const double imag = signal[k].imag();
    const double magnitude = vcl_sqrt( real * real + imag * imag );
    std::cout << k << "  " << magnitude << std::endl;
    }
  // Software Guide : EndCodeSnippet

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include "helpers.hpp"
#include <compress.hpp>

#include <vector>
#include <list>
#include <string>
#include <vector>
#include <iterator>
#include <utility>

#include "catch.hpp"

using iter::compress;
using itertest::SolidInt;
using itertest::BasicIterable;
using Vec = const std::vector<int>;

TEST_CASE("compress: alternating", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5, 6};
    std::vector<bool> bvec{true, false, true, false, true, false};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {1,3,5};

    REQUIRE( v  == vc );
}

TEST_CASE("compress: consecutive falses", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{true, false, false, false, true};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {1,5};

    REQUIRE( v == vc );
}

TEST_CASE("compress: consecutive trues", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{false, true, true, true, false};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {2,3,4};

    REQUIRE( v == vc );
}

TEST_CASE("compress: all true", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec(ivec.size(), true);
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));

    REQUIRE( v == ivec );
}

TEST_CASE("compress: all false", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec(ivec.size(), false);
    auto c = compress(ivec, bvec);
    REQUIRE( std::begin(c) == std::end(c) );
}

TEST_CASE("compress: binds to lvalues, moves rvalues", "[compress]") {
    BasicIterable<char> bi{'x', 'y', 'z'};
    std::vector<bool> bl{true, true, true};
    SECTION("binds to lvalues") {
        compress(bi, bl);
        REQUIRE_FALSE( bi.was_moved_from() );
    }
    SECTION("moves rvalues") {
        compress(std::move(bi), bl);
        REQUIRE( bi.was_moved_from() );
    }
}

struct BoolLike {
    public:
        bool state;
        explicit operator bool() const {
            return this->state;
        }
};

TEST_CASE("compress: workds with truthy and falsey values", "[compress]") {
    std::vector<BoolLike> bvec{{true}, {false}, {true}, {false}};

    Vec ivec{1,2,3,4};

    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));

    Vec vc = {1,3};
    REQUIRE( v == vc );
}

TEST_CASE("compress: terminates on shorter selectors", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{true};
    auto c = compress(ivec, bvec);
    REQUIRE( std::distance(std::begin(c), std::end(c)) == 1 );
}

TEST_CASE("compress: terminates on shorter data", "[compress]") {
    std::vector<int> ivec{1};
    std::vector<bool> bvec{true, true, true, true, true};
    auto c = compress(ivec, bvec);
    REQUIRE( std::distance(std::begin(c), std::end(c)) == 1 );
}
<commit_msg>tests compress with empty selectors<commit_after>#include "helpers.hpp"
#include <compress.hpp>

#include <vector>
#include <list>
#include <string>
#include <vector>
#include <iterator>
#include <utility>

#include "catch.hpp"

using iter::compress;
using itertest::SolidInt;
using itertest::BasicIterable;
using Vec = const std::vector<int>;

TEST_CASE("compress: alternating", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5, 6};
    std::vector<bool> bvec{true, false, true, false, true, false};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {1,3,5};

    REQUIRE( v  == vc );
}

TEST_CASE("compress: consecutive falses", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{true, false, false, false, true};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {1,5};

    REQUIRE( v == vc );
}

TEST_CASE("compress: consecutive trues", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{false, true, true, true, false};
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));
    Vec vc = {2,3,4};

    REQUIRE( v == vc );
}

TEST_CASE("compress: all true", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec(ivec.size(), true);
    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));

    REQUIRE( v == ivec );
}

TEST_CASE("compress: all false", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec(ivec.size(), false);
    auto c = compress(ivec, bvec);
    REQUIRE( std::begin(c) == std::end(c) );
}

TEST_CASE("compress: binds to lvalues, moves rvalues", "[compress]") {
    BasicIterable<char> bi{'x', 'y', 'z'};
    std::vector<bool> bl{true, true, true};
    SECTION("binds to lvalues") {
        compress(bi, bl);
        REQUIRE_FALSE( bi.was_moved_from() );
    }
    SECTION("moves rvalues") {
        compress(std::move(bi), bl);
        REQUIRE( bi.was_moved_from() );
    }
}

struct BoolLike {
    public:
        bool state;
        explicit operator bool() const {
            return this->state;
        }
};

TEST_CASE("compress: workds with truthy and falsey values", "[compress]") {
    std::vector<BoolLike> bvec{{true}, {false}, {true}, {false}};

    Vec ivec{1,2,3,4};

    auto c = compress(ivec, bvec);
    Vec v(std::begin(c), std::end(c));

    Vec vc = {1,3};
    REQUIRE( v == vc );
}

TEST_CASE("compress: terminates on shorter selectors", "[compress]") {
    std::vector<int> ivec{1, 2, 3, 4, 5};
    std::vector<bool> bvec{true};
    auto c = compress(ivec, bvec);
    REQUIRE( std::distance(std::begin(c), std::end(c)) == 1 );
}

TEST_CASE("compress: terminates on shorter data", "[compress]") {
    std::vector<int> ivec{1};
    std::vector<bool> bvec{true, true, true, true, true};
    auto c = compress(ivec, bvec);
    REQUIRE( std::distance(std::begin(c), std::end(c)) == 1 );
}

TEST_CASE("compress: nothing on empty selectors", "[compress]") {
    std::vector<int> ivec{1,2,3};
    std::vector<bool> bvec{};
    auto c = compress(ivec, bvec);
    REQUIRE( std::begin(c) == std::end(c) );
}
<|endoftext|>


<commit_before>#ifneq(,)
// in var: sParam: rstStruct.param1
// in var: sParamName: param1
// in var: sdoParam: rdoParam || rdoParam.CreateChild("$($sParam)")
#ifeqend
\
\
\
#var elementForm $(Interface.Options.*elementFormDefault)
#var attributeForm $(Interface.Options.*attributeFormDefault)
\
#ifeq($(.Name),Nillable||Optional)
#var recreateChild false
#else
#ifeq($(.Type),generic||string)
#var recreateChild false
#else
#var recreateChild $($sdoParam.!match/.CreateChild/)
#ifeqend
\
\
#ifneq($(.Options.*form),)
#ifeq($(.Options.*isAttribute),true||1)
#var attributeForm $(.Options.form)
#else
#var elementForm $(.Options.form)
#ifeqend
#ifeqend
#ifeq($(.Options.*isRef),true||1)
#var elementForm qualified
#ifeqend
\
#ifeqend // Nillable||Optional
\
#ifeq($($recreateChild),true)
#var doName tdoParam$($sParamName)
  staff::DataObject $($doName) = $($sdoParam);
#else
#var doName $($sdoParam)
#ifeqend
\
\
#ifeq($(.Name),Optional||Nillable)           // ######### Optional or Nillable ############
  if (!($($sOptMod)$($sParam)).IsNull()) // $(.Name)
  {
#cgpushvars
#var sOptMod $($sOptMod)*
#indent +
#context $(.TemplateParams.TemplateParam1)
#cginclude "TypeSerialization.cpp"
#contextend
#indent -
#cgpopvars
  }
#ifeq($(.Name),Nillable) // */
  else
  {
    $($doName).SetNil();
  }
#ifeqend
#else // not optional or nillable
\
#ifeq($($elementForm),qualified)
#ifneq($(.Type),generic||string)
#var elPath $($ThisElementPath)
#ifneq($($elPath.!match/.Class./),true) // don't set namespace for request element
#ifneq($(.Options.*targetNamespace||Interface.Options.*targetNamespace),)
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#ifeqend
#ifeqend
#ifeqend
#ifeqend
\
\
#ifeq($(.Name),Abstract)                     // ########## abstract #################

#ifeq($(.Options.*isAttribute),true||1) // attribute
#cgerror Can't serialize abstract member $($sParam) into attribute.
#ifeqend
#ifneq($(.TemplateParams.TemplateParam1.Type),struct)
#cgerror Abstract template type is not struct. Member $($sParam)
#ifeqend
  $($doName) << $($sOptMod)$($sParam);
#else                                        // ######### not abstract #####################
\
#ifeq($(.Options.*isAttribute),true||1)      // serialize to attribute
\
#ifeq($($attributeForm),qualified)
  std::string sPrefix$($sParamName);
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)", &sPrefix$($sParamName), false);
#var sAttrPrefix sPrefix$($sParamName) + ": \
#else
#var sAttrPrefix "
#ifeqend
\
#ifeq($(.Type),generic||string||typedef)
  $($doName).CreateAttribute($($sAttrPrefix)$(.Options.*elementName||$sParamName)", $($sOptMod)$($sParam));
#else
#ifeq($(.Type),enum)
  $($doName).CreateAttribute($($sAttrPrefix)$(.Options.*elementName||$sParamName)", \
::staff::SerializeEnum_$(.NsName.!mangle)_ToString($($sOptMod)$($sParam))$($attrFormDecl));
#else
#cgerror Cannot serialize type $(.Type) to attribute value. $($sParamName)
#ifeqend
#ifeqend
\
#else                                        // ############ common serialization ##########
\
\
#ifeq($(.Type),generic||string)                                // ==== generic, anyAttribute ====
#ifeq($(.Name),anyAttribute)
  for (anyAttribute::const_iterator itAttr = ($($sOptMod)$($sParam)).begin(),
       itAttrEnd = ($($sOptMod)$($sParam)).end(); itAttr != itAttrEnd; ++itAttr)
  {
    $($doName).AppendAttribute(const_cast<Attribute&>(*itAttr));
  }
#else
#ifeq($($sdoParam.!match/.CreateChild/),true)
#ifeq($($elementForm),qualified)
#var doName tdoParam$($sParamName)
  $($sdoParam.!depostfix/\)/), $($sOptMod)$($sParam)).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#else
  $($sdoParam.!depostfix/\)/), $($sOptMod)$($sParam));
#ifeqend
#else
#ifeq($($elementForm),qualified)
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#ifeqend // form
  $($doName).SetValue($($sOptMod)$($sParam));
#ifeqend  // param optimization
#ifeqend // anyAttribute
#else
\
\
#ifeq($(.Type),dataobject)                                     // ==== dataobject ====
  $($doName).AppendChild($($sOptMod)$($sParam));
#else
\
\
#ifeq($(.Type),typedef)
  SerializeTypedef_$(.NsName.!mangle)($($doName), $($sOptMod)$($sParam));
#else
\
\
#ifeq($(.Type),struct||enum)                                   // ==== enum, struct ====
  $($doName) << $($sOptMod)$($sParam);
#else
\
\
#ifeq($(.Namespace)$(.Name),staff::Array)                      // ### soapArray ###
#cginclude "ArraySerialization.cpp"
#else
\
#ifeq($(.Type),template)                                       // ==== template ====
  for ($(.NsName)::const_iterator itItem$($nItemLevel) = ($($sOptMod)$($sParam)).begin(),\
 itItem$($nItemLevel)End = ($($sOptMod)$($sParam)).end();
       itItem$($nItemLevel) != itItem$($nItemLevel)End; ++itItem$($nItemLevel))
  {
#var sItemName $(.Options.*itemName||"Item")
#ifeq($(.Name),map||multimap)                                  // ==== map ====
#ifeq($($bUseParentElement),true||1)
#var sdoItem $($doName)
#else
#var sdoItem tdoItem
    staff::DataObject $($sdoItem) = $($doName).CreateChild("$($sItemName)");
#ifeqend
\
#indent +
#context $(.TemplateParams.TemplateParam1)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var bUseParentElement
#var sOptMod
#var sParam itItem$($nItemLevelPrev)->first
#var sParamName Item
#var sdoParam $($sdoItem).CreateChild("Key")
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
\
#indent +
#context $(.TemplateParams.TemplateParam2)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var bUseParentElement
#var sOptMod
#var sParam itItem$($nItemLevelPrev)->second
#var sParamName Item
#var sdoParam $($sdoItem).CreateChild("Value")
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
#else
\
#ifeq($(.Name),list||vector)                                 // ==== list ====
#indent +
#context $(.TemplateParams.TemplateParam1)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var sOptMod
#var sParam (*itItem$($nItemLevelPrev))
#var sParamName Item
#ifeq($($bUseParentElement),true||1)
#var sdoItem $($doName)
#else
#var sdoParam $($doName).CreateChild("$($sItemName)")
#ifeqend
#var bUseParentElement
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
#else
#cgerror template type $(.NsName) is not supported
#ifeqend
#ifeqend
  }

#else
#cgerror unknown type($(.Type)) of sParamName: $(Struct.NsName)::$(.Name)
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend // abstract
#ifeqend // attribute
#ifeqend // optional or nillable
<commit_msg>codegen: fixed serializing of sub-containers<commit_after>#ifneq(,)
// in var: sParam: rstStruct.param1
// in var: sParamName: param1
// in var: sdoParam: rdoParam || rdoParam.CreateChild("$($sParam)")
#ifeqend
\
\
\
#var elementForm $(Interface.Options.*elementFormDefault)
#var attributeForm $(Interface.Options.*attributeFormDefault)
\
#ifeq($(.Name),Nillable||Optional)
#var recreateChild false
#else
#ifeq($(.Type),generic||string)
#var recreateChild false
#else
#var recreateChild $($sdoParam.!match/.CreateChild/)
#ifeqend
\
\
#ifneq($(.Options.*form),)
#ifeq($(.Options.*isAttribute),true||1)
#var attributeForm $(.Options.form)
#else
#var elementForm $(.Options.form)
#ifeqend
#ifeqend
#ifeq($(.Options.*isRef),true||1)
#var elementForm qualified
#ifeqend
\
#ifeqend // Nillable||Optional
\
#ifeq($($recreateChild),true)
#var doName tdoParam$($sParamName)$($nItemLevel)
  staff::DataObject $($doName) = $($sdoParam);
#else
#var doName $($sdoParam)
#ifeqend
\
\
#ifeq($(.Name),Optional||Nillable)           // ######### Optional or Nillable ############
  if (!($($sOptMod)$($sParam)).IsNull()) // $(.Name)
  {
#cgpushvars
#var sOptMod $($sOptMod)*
#indent +
#context $(.TemplateParams.TemplateParam1)
#cginclude "TypeSerialization.cpp"
#contextend
#indent -
#cgpopvars
  }
#ifeq($(.Name),Nillable) // */
  else
  {
    $($doName).SetNil();
  }
#ifeqend
#else // not optional or nillable
\
#ifeq($($elementForm),qualified)
#ifneq($(.Type),generic||string)
#var elPath $($ThisElementPath)
#ifneq($($elPath.!match/.Class./),true) // don't set namespace for request element
#ifneq($(.Options.*targetNamespace||Interface.Options.*targetNamespace),)
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#ifeqend
#ifeqend
#ifeqend
#ifeqend
\
\
#ifeq($(.Name),Abstract)                     // ########## abstract #################

#ifeq($(.Options.*isAttribute),true||1) // attribute
#cgerror Can't serialize abstract member $($sParam) into attribute.
#ifeqend
#ifneq($(.TemplateParams.TemplateParam1.Type),struct)
#cgerror Abstract template type is not struct. Member $($sParam)
#ifeqend
  $($doName) << $($sOptMod)$($sParam);
#else                                        // ######### not abstract #####################
\
#ifeq($(.Options.*isAttribute),true||1)      // serialize to attribute
\
#ifeq($($attributeForm),qualified)
  std::string sPrefix$($sParamName);
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)", &sPrefix$($sParamName), false);
#var sAttrPrefix sPrefix$($sParamName) + ": \
#else
#var sAttrPrefix "
#ifeqend
\
#ifeq($(.Type),generic||string||typedef)
  $($doName).CreateAttribute($($sAttrPrefix)$(.Options.*elementName||$sParamName)", $($sOptMod)$($sParam));
#else
#ifeq($(.Type),enum)
  $($doName).CreateAttribute($($sAttrPrefix)$(.Options.*elementName||$sParamName)", \
::staff::SerializeEnum_$(.NsName.!mangle)_ToString($($sOptMod)$($sParam))$($attrFormDecl));
#else
#cgerror Cannot serialize type $(.Type) to attribute value. $($sParamName)
#ifeqend
#ifeqend
\
#else                                        // ############ common serialization ##########
\
\
#ifeq($(.Type),generic||string)                                // ==== generic, anyAttribute ====
#ifeq($(.Name),anyAttribute)
  for (anyAttribute::const_iterator itAttr = ($($sOptMod)$($sParam)).begin(),
       itAttrEnd = ($($sOptMod)$($sParam)).end(); itAttr != itAttrEnd; ++itAttr)
  {
    $($doName).AppendAttribute(const_cast<Attribute&>(*itAttr));
  }
#else
#ifeq($($sdoParam.!match/.CreateChild/),true)
#ifeq($($elementForm),qualified)
#var doName tdoParam$($sParamName)$($nItemLevel)
  $($sdoParam.!depostfix/\)/), $($sOptMod)$($sParam)).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#else
  $($sdoParam.!depostfix/\)/), $($sOptMod)$($sParam));
#ifeqend
#else
#ifeq($($elementForm),qualified)
  $($doName).SetNamespaceUriGenPrefix("$(.Options.*targetNamespace||Interface.Options.*targetNamespace)");
#ifeqend // form
  $($doName).SetValue($($sOptMod)$($sParam));
#ifeqend  // param optimization
#ifeqend // anyAttribute
#else
\
\
#ifeq($(.Type),dataobject)                                     // ==== dataobject ====
  $($doName).AppendChild($($sOptMod)$($sParam));
#else
\
\
#ifeq($(.Type),typedef)
  SerializeTypedef_$(.NsName.!mangle)($($doName), $($sOptMod)$($sParam));
#else
\
\
#ifeq($(.Type),struct||enum)                                   // ==== enum, struct ====
  $($doName) << $($sOptMod)$($sParam);
#else
\
\
#ifeq($(.Namespace)$(.Name),staff::Array)                      // ### soapArray ###
#cginclude "ArraySerialization.cpp"
#else
\
#ifeq($(.Type),template)                                       // ==== template ====
  for ($(.NsName)::const_iterator itItem$($nItemLevel) = ($($sOptMod)$($sParam)).begin(),\
 itItem$($nItemLevel)End = ($($sOptMod)$($sParam)).end();
       itItem$($nItemLevel) != itItem$($nItemLevel)End; ++itItem$($nItemLevel))
  {
#var sItemName $(.Options.*itemName||"Item")
#ifeq($(.Name),map||multimap)                                  // ==== map ====
#ifeq($($bUseParentElement),true||1)
#var sdoItem $($doName)
#else
#var sdoItem tdoItem
    staff::DataObject $($sdoItem) = $($doName).CreateChild("$($sItemName)");
#ifeqend
\
#indent +
#context $(.TemplateParams.TemplateParam1)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var bUseParentElement
#var sOptMod
#var sParam itItem$($nItemLevelPrev)->first
#var sParamName Item
#var sdoParam $($sdoItem).CreateChild("Key")
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
\
#indent +
#context $(.TemplateParams.TemplateParam2)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var bUseParentElement
#var sOptMod
#var sParam itItem$($nItemLevelPrev)->second
#var sParamName Item
#var sdoParam $($sdoItem).CreateChild("Value")
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
#else
\
#ifeq($(.Name),list||vector)                                 // ==== list ====
#indent +
#context $(.TemplateParams.TemplateParam1)
#cgpushvars
#var nItemLevelPrev $($nItemLevel)
#var nItemLevel $($nItemLevel.!inc.!trunc)
#var sOptMod
#var sParam (*itItem$($nItemLevelPrev))
#var sParamName Item
#ifeq($($bUseParentElement),true||1)
#var sdoItem $($doName)
#else
#var sdoParam $($doName).CreateChild("$($sItemName)")
#ifeqend
#var bUseParentElement
#cginclude "TypeSerialization.cpp"
#cgpopvars
#contextend
#indent -
#else
#cgerror template type $(.NsName) is not supported
#ifeqend
#ifeqend
  }

#else
#cgerror unknown type($(.Type)) of sParamName: $(Struct.NsName)::$(.Name)
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend // abstract
#ifeqend // attribute
#ifeqend // optional or nillable
<|endoftext|>


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

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "python_api.h"

#include "c_api_internal.h"

namespace tensorflow {

void UpdateEdge(TF_Graph* graph, TF_Output new_src, TF_Input dst, TF_Status* status) {
  mutex_lock l(graph->mu);
  status->status = graph->graph.UpdateEdge(&new_src.oper->node, new_src.index, &dst.oper->node, dst.index);
}

void AddControlInput(TF_Graph* graph, TF_Operation* op, TF_Operation* input) {
  mutex_lock l(graph->mu);
  graph->graph.AddControlEdge(&input->node, &op->node);
}

void ClearControlInputs(TF_Graph* graph, TF_Operation* op) {
  mutex_lock l(graph->mu);
  for (const auto* edge : op->node.in_edges()) {
    if (edge->IsControlEdge()) {
      graph->graph.RemoveControlEdge(edge);
    }
  }
}

void SetRequestedDevice(TF_Graph* graph, TF_Operation* op, const char* device) {
  mutex_lock l(graph->mu);
  op->node.set_requested_device(device);
}

}  // namespace tensorflow
<commit_msg>Updated the Python API C++ file.<commit_after>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "python_api.h"

#include "c_api_internal.h"

namespace tensorflow {

void UpdateEdge(TF_Graph* graph, TF_Output new_src, TF_Input dst,
                TF_Status* status) {
  mutex_lock l(graph->mu);
  tensorflow::shape_inference::InferenceContext* ic =
      graph->refiner.GetContext(&new_src.oper->node);

  if (ic->num_outputs() <= new_src.index) {
    status->status = tensorflow::errors::OutOfRange(
        "Cannot update edge. Output index [", new_src.index,
        "] is greater than the number of total outputs [", ic->num_outputs(),
        "].");
    return;
  }
  tensorflow::shape_inference::ShapeHandle shape = ic->output(new_src.index);

  tensorflow::shape_inference::InferenceContext* ic_dst =
      graph->refiner.GetContext(&dst.oper->node);
  if (ic_dst->num_inputs() <= dst.index) {
    status->status = tensorflow::errors::OutOfRange(
        "Cannot update edge. Input index [", dst.index,
        "] is greater than the number of total inputs [", ic_dst->num_inputs(),
        "].");
    return;
  }
  if (!ic_dst->MergeInput(dst.index, shape)) {
    status->status = tensorflow::errors::InvalidArgument(
        "Cannot update edge, incompatible shapes: ", ic_dst->DebugString(shape),
        " and ", ic_dst->DebugString(ic_dst->input(dst.index)), ".");
    return;
  }
  status->status = graph->graph.UpdateEdge(&new_src.oper->node, new_src.index,
                                           &dst.oper->node, dst.index);
}

void AddControlInput(TF_Graph* graph, TF_Operation* op, TF_Operation* input) {
  mutex_lock l(graph->mu);
  graph->graph.AddControlEdge(&input->node, &op->node);
}

void ClearControlInputs(TF_Graph* graph, TF_Operation* op) {
  mutex_lock l(graph->mu);
  for (const auto* edge : op->node.in_edges()) {
    if (edge->IsControlEdge()) {
      graph->graph.RemoveControlEdge(edge);
    }
  }
}

void SetRequestedDevice(TF_Graph* graph, TF_Operation* op, const char* device) {
  mutex_lock l(graph->mu);
  op->node.set_requested_device(device);
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File: ConstantExpression.hpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description:
//
///////////////////////////////////////////////////////////////////////////////

#ifndef NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP
#define NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP
#ifdef NEKTAR_USE_EXPRESSION_TEMPLATES

#include <boost/call_traits.hpp>

#include <LibUtilities/ExpressionTemplates/ExpressionReturnType.hpp>
#include <LibUtilities/ExpressionTemplates/Expression.hpp>
#include <LibUtilities/ExpressionTemplates/ExpressionMetadata.hpp>
#include <LibUtilities/ExpressionTemplates/Accumulator.hpp>
#include <LibUtilities/ExpressionTemplates/ConstantExpressionTraits.hpp>
#include <LibUtilities/ExpressionTemplates/NullOp.hpp>

#include <LibUtilities/BasicUtils/ErrorUtil.hpp>

namespace Nektar
{
    template<typename Type>
    class ConstantExpressionPolicy
    {
        public:
            typedef Type ResultType;
            typedef typename boost::call_traits<Type>::const_reference DataType;
            typedef ConstantNullOp NullOp;
            typedef typename ConstantExpressionTraits<Type>::MetadataType MetadataType;

        public:
            static void InitializeMetadata(typename boost::call_traits<DataType>::const_reference data, MetadataType& m)
            {
                m = MetadataType(data);
            }

            static void Evaluate(Accumulator<ResultType>& accum, typename boost::call_traits<DataType>::const_reference d)
            {
                *accum = d;
            }

            template<template <typename, typename> class ParentOpType>
            static void Evaluate(Accumulator<ResultType>& accum, typename boost::call_traits<DataType>::const_reference d)
            {
                ParentOpType<ResultType, DataType>::ApplyEqual(accum, d);
            }

            template<typename CheckType>
            static typename boost::enable_if<boost::is_same<CheckType, Type>, bool>::type
            ContainsReference(const CheckType& result, DataType m_data)
            {
                return &result == &m_data;
            }

            template<typename CheckType>
            static typename boost::disable_if<boost::is_same<CheckType, Type>, bool>::type
            ContainsReference(const CheckType& result, DataType m_data)
            {
                return false;
            }

            static void Print(std::ostream& os, typename boost::call_traits<DataType>::const_reference data)
            {
                os << data;
            }
    };

    template<typename DataType>
    Expression<ConstantExpressionPolicy<DataType> > MakeExpr(const DataType& rhs)
    {
        return Expression<ConstantExpressionPolicy<DataType> >(rhs);
    }

    template<typename T>
    struct IsConstantExpressionPolicy : public boost::false_type {};

    template<typename T>
    struct IsConstantExpressionPolicy<ConstantExpressionPolicy<T> > : public boost::true_type {};
}

#endif //NEKTAR_USE_EXPRESSION_TEMPLATES
#endif // NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP

/**
    $Log: ConstantExpression.hpp,v $
    Revision 1.15  2008/01/03 04:16:41  bnelson
    Changed method name in the expression library from Apply to Evaluate.

    Revision 1.14  2008/01/02 20:11:22  bnelson
    Fixed error detecting if incoming type was the same as the constant expression's type when looking for aliasing.

    Revision 1.13  2008/01/02 18:20:12  bnelson
    *** empty log message ***

    Revision 1.12  2007/12/19 05:09:21  bnelson
    First pass at detecting aliasing.  Still need to test performance implications.

    Revision 1.11  2007/11/13 18:05:27  bnelson
    Added MakeExpr helper function.

    Revision 1.10  2007/10/04 03:48:54  bnelson
    *** empty log message ***

    Revision 1.9  2007/08/16 02:14:21  bnelson
    Moved expression templates to the Nektar namespace.

    Revision 1.8  2007/01/30 23:37:16  bnelson
    *** empty log message ***

    Revision 1.7  2007/01/16 17:37:55  bnelson
    Wrapped everything with #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES

    Revision 1.6  2007/01/16 05:29:50  bnelson
    Major improvements for expression templates.

    Revision 1.5  2006/09/14 02:08:59  bnelson
    Fixed gcc compile errors

    Revision 1.4  2006/09/11 03:24:24  bnelson
    Updated expression templates so they are all specializations of an Expression object, using policies to differentiate.

    Revision 1.3  2006/08/28 02:39:53  bnelson
    *** empty log message ***

    Revision 1.2  2006/08/25 01:33:47  bnelson
    no message

    Revision 1.1  2006/06/01 09:20:55  kirby
    *** empty log message ***

    Revision 1.1  2006/05/04 18:57:41  kirby
    *** empty log message ***

    Revision 1.2  2006/01/31 13:51:12  bnelson
    Updated for new configure.

    Revision 1.1  2006/01/10 14:50:30  bnelson
    Initial Revision.

**/

<commit_msg>Alias checks now look at the actual array held by vectors and matrices.<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File: ConstantExpression.hpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description:
//
///////////////////////////////////////////////////////////////////////////////

#ifndef NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP
#define NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP
#ifdef NEKTAR_USE_EXPRESSION_TEMPLATES

#include <boost/call_traits.hpp>

#include <LibUtilities/ExpressionTemplates/ExpressionReturnType.hpp>
#include <LibUtilities/ExpressionTemplates/Expression.hpp>
#include <LibUtilities/ExpressionTemplates/ExpressionMetadata.hpp>
#include <LibUtilities/ExpressionTemplates/Accumulator.hpp>
#include <LibUtilities/ExpressionTemplates/ConstantExpressionTraits.hpp>
#include <LibUtilities/ExpressionTemplates/NullOp.hpp>

#include <LibUtilities/BasicUtils/ErrorUtil.hpp>

#include <LibUtilities/LinearAlgebra/NekVectorFwd.hpp>
#include <LibUtilities/LinearAlgebra/NekMatrixFwd.hpp>

namespace Nektar
{
    template<typename Type>
    class ConstantExpressionPolicy
    {
        public:
            typedef Type ResultType;
            typedef typename boost::call_traits<Type>::const_reference DataType;
            typedef ConstantNullOp NullOp;
            typedef typename ConstantExpressionTraits<Type>::MetadataType MetadataType;

        public:
            static void InitializeMetadata(typename boost::call_traits<DataType>::const_reference data, MetadataType& m)
            {
                m = MetadataType(data);
            }

            static void Evaluate(Accumulator<ResultType>& accum, typename boost::call_traits<DataType>::const_reference d)
            {
                *accum = d;
            }

            template<template <typename, typename> class ParentOpType>
            static void Evaluate(Accumulator<ResultType>& accum, typename boost::call_traits<DataType>::const_reference d)
            {
                ParentOpType<ResultType, DataType>::ApplyEqual(accum, d);
            }

            template<typename CheckType>
            static typename boost::enable_if
                            <
                                boost::mpl::and_
                                <
                                    boost::is_same<CheckType, Type>,
                                    boost::mpl::or_
                                    <
                                        IsVector<typename boost::remove_cv<CheckType>::type>,
                                        IsMatrix<typename boost::remove_cv<CheckType>::type>
                                    >
                                >, bool>::type
            ContainsReference(const CheckType& result, DataType m_data)
            {
                return result.GetPtr().data() == m_data.GetPtr().data();
            }

            template<typename CheckType>
            static typename boost::enable_if
                            <
                                boost::mpl::and_
                                <
                                    boost::is_same<CheckType, Type>,
                                    boost::mpl::and_
                                    <
                                        boost::mpl::not_<IsVector<typename boost::remove_cv<CheckType>::type> >,
                                        boost::mpl::not_<IsMatrix<typename boost::remove_cv<CheckType>::type> >
                                    >
                                >, bool>::type
            ContainsReference(const CheckType& result, DataType m_data)
            {
                return &result == &m_data;
            }

            template<typename CheckType>
            static typename boost::disable_if<boost::is_same<CheckType, Type>, bool>::type
            ContainsReference(const CheckType& result, DataType m_data)
            {
                return false;
            }

            static void Print(std::ostream& os, typename boost::call_traits<DataType>::const_reference data)
            {
                os << data;
            }
    };

    template<typename DataType>
    Expression<ConstantExpressionPolicy<DataType> > MakeExpr(const DataType& rhs)
    {
        return Expression<ConstantExpressionPolicy<DataType> >(rhs);
    }

    template<typename T>
    struct IsConstantExpressionPolicy : public boost::false_type {};

    template<typename T>
    struct IsConstantExpressionPolicy<ConstantExpressionPolicy<T> > : public boost::true_type {};
}

#endif //NEKTAR_USE_EXPRESSION_TEMPLATES
#endif // NEKTAR_LIB_UTILITIES_CONSTANT_EXPRESSION_HPP

/**
    $Log: ConstantExpression.hpp,v $
    Revision 1.16  2008/01/20 04:01:05  bnelson
    Expression template updates.

    Revision 1.15  2008/01/03 04:16:41  bnelson
    Changed method name in the expression library from Apply to Evaluate.

    Revision 1.14  2008/01/02 20:11:22  bnelson
    Fixed error detecting if incoming type was the same as the constant expression's type when looking for aliasing.

    Revision 1.13  2008/01/02 18:20:12  bnelson
    *** empty log message ***

    Revision 1.12  2007/12/19 05:09:21  bnelson
    First pass at detecting aliasing.  Still need to test performance implications.

    Revision 1.11  2007/11/13 18:05:27  bnelson
    Added MakeExpr helper function.

    Revision 1.10  2007/10/04 03:48:54  bnelson
    *** empty log message ***

    Revision 1.9  2007/08/16 02:14:21  bnelson
    Moved expression templates to the Nektar namespace.

    Revision 1.8  2007/01/30 23:37:16  bnelson
    *** empty log message ***

    Revision 1.7  2007/01/16 17:37:55  bnelson
    Wrapped everything with #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES

    Revision 1.6  2007/01/16 05:29:50  bnelson
    Major improvements for expression templates.

    Revision 1.5  2006/09/14 02:08:59  bnelson
    Fixed gcc compile errors

    Revision 1.4  2006/09/11 03:24:24  bnelson
    Updated expression templates so they are all specializations of an Expression object, using policies to differentiate.

    Revision 1.3  2006/08/28 02:39:53  bnelson
    *** empty log message ***

    Revision 1.2  2006/08/25 01:33:47  bnelson
    no message

    Revision 1.1  2006/06/01 09:20:55  kirby
    *** empty log message ***

    Revision 1.1  2006/05/04 18:57:41  kirby
    *** empty log message ***

    Revision 1.2  2006/01/31 13:51:12  bnelson
    Updated for new configure.

    Revision 1.1  2006/01/10 14:50:30  bnelson
    Initial Revision.

**/

<|endoftext|>