Hello :)
I'd like to package a library I'm working on as a Header-Only library to make it easier for clients to use the library (it's small and there's really no reason to make it a separate translation item). However, I cannot simply put my code in headers because such a location would violate C++'s one definition rule if a project used my library header multiple times within the same project.
How does one modify a library to make it header-only?
Billy3
EDIT: Here's example code from my 'library':
FileSystem/File.hpp:
#pragma once
#include <algorithm>
#include <string>
#include <windows.h>
namespace WindowsAPI { namespace FileSystem {
class File
{
HANDLE handle;
public:
File( const std::wstring& fileName,
DWORD desiredAccess,
DWORD shareMode,
LPSECURITY_ATTRIBUTES securityAttributes,
DWORD creationDisposition,
DWORD flagsAndAttributes,
File * const templateFile );
File( const File& );
~File();
const File& operator=( File );
File& swap(File&);
HANDLE getWindowsHandle() const { return handle; };
};
}} //Namespaces
FileSystem/File.cpp
#include "File.hpp"
#include "../Exception.hpp"
namespace WindowsAPI { namespace FileSystem {
File::File( const std::wstring& fileName,
DWORD desiredAccess,
DWORD shareMode,
LPSECURITY_ATTRIBUTES securityAttributes,
DWORD creationDisposition,
DWORD flagsAndAttributes,
File * const templateFile )
{
handle = CreateFileW(
fileName.c_str(),
desiredAccess,
shareMode,
securityAttributes,
creationDisposition,
flagsAndAttributes,
templateFile ? templateFile->handle : NULL);
if (handle == INVALID_HANDLE_VALUE)
WindowsApiException::ThrowFromLastError();
}
File::File( const File& other )
{
BOOL errorCheck;
errorCheck =
DuplicateHandle(
GetCurrentProcess(),
other.handle,
GetCurrentProcess(),
&this->handle,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if (!errorCheck)
WindowsApiException::ThrowFromLastError();
}
File::~File()
{
if (!CloseHandle(handle))
WindowsApiException::ThrowFromLastError();
}
const File& File::operator=(File other)
{
swap(other);
return *this;
}
File& File::swap(File& other)
{
std::swap(handle, other.handle);
return *this;
}
}}
template<> void std::swap<WindowsAPI::FileSystem::File>(WindowsAPI::FileSystem::File& a, WindowsAPI::FileSystem::File& b)
{
a.swap(b);
}