Remove boost any usage of boost libraries

shapetextures
Julius Michaelis 2015-09-29 10:32:54 +02:00
parent 0d1a0241f9
commit ee859d85e0
16 changed files with 150 additions and 240 deletions

View File

@ -57,12 +57,6 @@ CMAKE_DEPENDENT_OPTION(USE_GTK3 "Use GTK3 instead of GTK2" OFF "USE_GTK" OFF)
CMAKE_DEPENDENT_OPTION(USE_COCOA "Use Apple Cocoa for the developer mode and the windows." ON "APPLE" OFF)
option(WITH_AUTOMATIC_UPDATE "Automatic updates are downloaded from the project website." OFF)
# We link Boost statically because that makes it easier for us to distribute
# the resulting binary. Distributions have the ability to guarantee a certain
# version of the library exists on the system though, so they may prefer
# dynamic linking.
option(USE_STATIC_BOOST "Link Boost libraries statically" ON)
# Allow distributions to use the system tinyxml instead of our bundled copy.
option(USE_SYSTEM_TINYXML "Use system tinyxml library" OFF)
@ -87,17 +81,16 @@ endif()
REQUIRE_CXX_SOURCE_COMPILES("#include <memory>\nint main() { std::unique_ptr<int> a; std::shared_ptr<int> b; }" HAVE_C11_SMART_PTRS)
CHECK_CXX_SOURCE_COMPILES("int main() { void *d = nullptr; }" HAVE_NULLPTR)
CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STATIC_ASSERT)
REQUIRE_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STATIC_ASSERT)
CHECK_CXX_SOURCE_COMPILES("#include <memory>\nint main() { auto a = std::make_unique<int>(0); }" HAVE_MAKE_UNIQUE)
CHECK_CXX_SOURCE_COMPILES("template<class... T> class C; int main() { return 0; }" HAVE_VARIADIC_TEMPLATES)
REQUIRE_CXX_SOURCE_COMPILES("template<class... T> class C; int main() { return 0; }" HAVE_VARIADIC_TEMPLATES)
# g++'s libstdc++ doesn't properly support <regex> until 4.9.
# They ship a header that declares functions, but they don't ship an
# implementation for some things (like std::regex_iterator).
# This needs to test *linking*, not compilation; cmake does both at the same
# time, so the test below works.
CHECK_CXX_SOURCE_COMPILES("#include <regex>\nint main() { std::cregex_iterator ri; }" HAVE_WORKING_REGEX)
CMAKE_DEPENDENT_OPTION(USE_BOOST_REGEX "Use Boost.Regex even if the C++ runtime has a working implementation of <regex>" OFF "HAVE_WORKING_REGEX" ON)
REQUIRE_CXX_SOURCE_COMPILES("#include <regex>\nint main() { std::cregex_iterator ri; }" HAVE_WORKING_REGEX)
if(MSVC_VERSION GREATER 1499)
list(APPEND OC_CXX_FLAGS /MP)
@ -820,15 +813,6 @@ find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)
include_directories(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
set(Boost_ADDITIONAL_VERSIONS
# FindBoost.cmake goes up to 1.56.0
"1.59.0" "1.59"
"1.58.0" "1.58"
"1.57.0" "1.57"
)
find_package("Boost" 1.40.0 REQUIRED)
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
if(CMAKE_SYSTEM MATCHES "Windows")
message(STATUS "Using Win32 threading.")
else()
@ -1425,15 +1409,6 @@ if(UPNP_FOUND)
target_link_libraries(openclonk ${UPNP_LIBRARIES})
endif()
if(USE_BOOST_REGEX)
SET(Boost_USE_STATIC_LIBS ${USE_STATIC_BOOST})
find_package(Boost 1.40.0 REQUIRED COMPONENTS regex)
# Disable automatic linking, we'll do it ourselves
add_definitions(-DBOOST_REGEX_NO_LIB)
target_link_libraries(libc4script ${Boost_REGEX_LIBRARY})
target_link_libraries(c4group ${Boost_REGEX_LIBRARY})
endif()
add_subdirectory(tests EXCLUDE_FROM_ALL)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)

11
README
View File

@ -17,14 +17,13 @@ Additionally, OpenClonk depends on a number of third-party libraries:
- The OpenGL Extension Wrangler Library (http://glew.sourceforge.net/)
- FreeALUT (https://github.com/vancegroup/freealut)
- libogg and libvorbis (https://www.xiph.org/downloads/)
- Boost (http://www.boost.org/users/download/)
OS X Specific
=============
OpenClonk supports OS X versions 10.8 "Mountain Lion" and later.
If you are using brew (https://github.com/mxcl/homebrew) or MacPorts
(http://www.macports.org/), the packages you'll have to install are:
libjpeg, libpng, freetype, glew, libogg, libvorbis, boost
libjpeg, libpng, freetype, glew, libogg, libvorbis
Linux Specific
==============
@ -38,10 +37,10 @@ to the ones listed above:
- libxrandr
Most distributions should provide these dependencies via their packaging
system. For Debian based distributions, you will need these packages:
build-essential cmake imagemagick libboost-dev libboost-regex-dev
libfreetype6-dev libgl1-mesa-dev libglew-dev libgtk2.0-dev libjpeg-dev
libpng-dev libsdl1.2-dev libsdl-mixer1.2-dev libupnp-dev libxrandr-dev
x11proto-core-dev zlib1g-dev
build-essential cmake imagemagick libfreetype6-dev libgl1-mesa-dev
libglew-dev libgtk2.0-dev libjpeg-dev libpng-dev libsdl1.2-dev
libsdl-mixer1.2-dev libupnp-dev libxrandr-dev x11proto-core-dev
zlib1g-dev
Windows Specific
================

View File

@ -27,10 +27,6 @@ don't need to include this file or any of the files it includes. */
#include "PlatformAbstraction.h"
// boost headers - after PlatformAbstraction to prevent redefines of stdint
#include <boost/function.hpp>
#include <boost/bind.hpp>
#define DEBUGREC_SCRIPT
#define DEBUGREC_START_FRAME 0
#define DEBUGREC_PXS
@ -67,15 +63,10 @@ don't need to include this file or any of the files it includes. */
#include <utility>
#include <vector>
#ifdef USE_BOOST_REGEX
# include <boost/regex.hpp>
namespace re = boost;
#else
# include <regex>
namespace re = std;
#endif
#include <regex>
namespace re = std;
// debug memory management - must come after standard and boost headers,
// debug memory management - must come after standard headers,
// because those libraries use placement new
#ifndef NODEBUGMEM
#if defined(_DEBUG) && defined(_MSC_VER)

View File

@ -16,7 +16,6 @@
#include <C4FacetEx.h>
#include <StdScheduler.h>
#include <boost/noncopyable.hpp>
#ifndef INC_C4Particles
@ -328,8 +327,7 @@ public:
};
// a chunk contains all of the single particles that can be drawn with one draw call (~"have certain similar attributes")
// this is noncopyable to make sure that the OpenGL buffers are never freed multiple times
class C4ParticleChunk : public boost::noncopyable
class C4ParticleChunk
{
private:
C4ParticleDef *sourceDefinition;
@ -356,6 +354,9 @@ public:
{
}
// this is noncopyable to make sure that the OpenGL buffers are never freed multiple times
C4ParticleChunk(const C4ParticleChunk&) = delete;
C4ParticleChunk& operator=(const C4ParticleChunk&) = delete;
~C4ParticleChunk()
{
Clear();
@ -377,7 +378,7 @@ public:
// this class must not be copied, because deleting the contained CStdCSec twice would be fatal
// a particle list belongs to a game-world entity (objects or global particles) and contains the chunks associated with that entity
class C4ParticleList : public boost::noncopyable
class C4ParticleList
{
private:
std::list<C4ParticleChunk*> particleChunks;
@ -395,6 +396,9 @@ public:
{
}
// non-copyable
C4ParticleList(const C4ParticleList&) = delete;
C4ParticleList& operator=(const C4ParticleList&) = delete;
~C4ParticleList() { Clear(); }

View File

@ -34,11 +34,10 @@ DEALINGS IN THE SOFTWARE.
#ifndef LIB_SHA1_H
#define LIB_SHA1_H
#include <boost/static_assert.hpp>
#include <cstddef>
BOOST_STATIC_ASSERT(sizeof(unsigned char)*8 == 8);
BOOST_STATIC_ASSERT(sizeof(unsigned int)*8 == 32);
static_assert(sizeof(unsigned char)*8 == 8, "Please reboot the C universe.");
static_assert(sizeof(unsigned int)*8 == 32, "sizeof(unsigned int) == 4");
#define SHA_DIGEST_LENGTH 20

View File

@ -23,18 +23,17 @@
#include "StdMeshMaterial.h"
#include <cassert>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
namespace
{
bool VertexDeclarationIsSane(const boost::ptr_vector<Ogre::Mesh::ChunkGeometryVertexDeclElement> &decl, const char *filename)
using Ogre::unique_ptr_vector;
bool VertexDeclarationIsSane(const unique_ptr_vector<Ogre::Mesh::ChunkGeometryVertexDeclElement> &decl, const char *filename)
{
bool semanticSeen[Ogre::Mesh::ChunkGeometryVertexDeclElement::VDES_MAX + 1] = { false };
BOOST_FOREACH(Ogre::Mesh::ChunkGeometryVertexDeclElement element, decl)
for(auto& element: decl)
{
switch (element.semantic)
switch (element->semantic)
{
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDES_Texcoords:
// FIXME: The Ogre format supports denoting multiple texture coordinates, but the rendering code only supports one
@ -45,14 +44,14 @@ namespace
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDES_Diffuse:
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDES_Specular:
// Only one set of each of these elements allowed
if (semanticSeen[element.semantic])
if (semanticSeen[element->semantic])
return false;
break;
default:
// We ignore unhandled element semantics.
break;
}
semanticSeen[element.semantic] = true;
semanticSeen[element->semantic] = true;
}
return true;
}
@ -60,7 +59,7 @@ namespace
template<size_t N>
void ReadNormalizedVertexData(float (&dest)[N], const char *source, Ogre::Mesh::ChunkGeometryVertexDeclElement::Type vdet)
{
BOOST_STATIC_ASSERT(N >= 4);
static_assert(N >= 4, "");
dest[0] = dest[1] = dest[2] = 0; dest[3] = 1;
switch (vdet)
{
@ -97,10 +96,10 @@ namespace
// Get maximum size of a vertex according to the declaration
std::map<int, size_t> max_offset;
BOOST_FOREACH(const Ogre::Mesh::ChunkGeometryVertexDeclElement &el, geo.vertexDeclaration)
for(const auto &el: geo.vertexDeclaration)
{
size_t elsize = 0;
switch (el.type)
switch (el->type)
{
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDET_Float1: elsize = sizeof(float) * 1; break;
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDET_Float2: elsize = sizeof(float) * 2; break;
@ -110,23 +109,23 @@ namespace
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDET_Color_ARGB: elsize = sizeof(uint8_t) * 4; break;
default: assert(!"Unexpected enum value"); break;
}
max_offset[el.source] = std::max<size_t>(max_offset[el.source], el.offset + elsize);
max_offset[el->source] = std::max<size_t>(max_offset[el->source], el->offset + elsize);
}
// Generate array of vertex buffer cursors
std::map<int, const char *> cursors;
BOOST_FOREACH(const Ogre::Mesh::ChunkGeometryVertexBuffer &buf, geo.vertexBuffers)
for(const auto &buf: geo.vertexBuffers)
{
if (cursors.find(buf.index) != cursors.end())
if (cursors.find(buf->index) != cursors.end())
throw Ogre::MultipleSingletonChunks("Multiple vertex buffers were bound to the same stream");
cursors[buf.index] = static_cast<const char *>(buf.data->data);
cursors[buf->index] = static_cast<const char *>(buf->data->data);
// Check that the vertices don't overlap
if (buf.vertexSize < max_offset[buf.index])
if (buf->vertexSize < max_offset[buf->index])
throw Ogre::InsufficientData("Vertices overlapping");
// Check that the vertex buffer has enough room for all vertices
if (buf.GetSize() < (geo.vertexCount - 1) * buf.vertexSize + max_offset[buf.index])
if (buf->GetSize() < (geo.vertexCount - 1) * buf->vertexSize + max_offset[buf->index])
throw Ogre::InsufficientData("Vertex buffer too small");
max_offset.erase(buf.index);
max_offset.erase(buf->index);
}
if (!max_offset.empty())
@ -143,11 +142,11 @@ namespace
vertex.u = vertex.v = 0;
bool read_tex = false;
// Read vertex declaration
BOOST_FOREACH(Ogre::Mesh::ChunkGeometryVertexDeclElement element, geo.vertexDeclaration)
for(const auto& element: geo.vertexDeclaration)
{
float values[4];
ReadNormalizedVertexData(values, cursors[element.source] + element.offset, element.type);
switch (element.semantic)
ReadNormalizedVertexData(values, cursors[element->source] + element->offset, element->type);
switch (element->semantic)
{
case Ogre::Mesh::ChunkGeometryVertexDeclElement::VDES_Position:
vertex.x = values[0];
@ -173,8 +172,8 @@ namespace
}
vertices.push_back(OgreToClonk::TransformVertex(vertex));
// Advance vertex buffer cursors
BOOST_FOREACH(const Ogre::Mesh::ChunkGeometryVertexBuffer &buf, geo.vertexBuffers)
cursors[buf.index] += buf.vertexSize;
for(const std::unique_ptr<Ogre::Mesh::ChunkGeometryVertexBuffer> &buf: geo.vertexBuffers)
cursors[buf->index] += buf->vertexSize;
}
return vertices;
@ -306,18 +305,18 @@ std::shared_ptr<StdMeshSkeleton> StdMeshSkeletonLoader::GetSkeletonByName(const
void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char* filename, const char *sourcefile, size_t size)
{
boost::scoped_ptr<Ogre::Skeleton::Chunk> chunk;
std::unique_ptr<Ogre::Skeleton::Chunk> chunk;
Ogre::DataStream stream(sourcefile, size);
std::shared_ptr<StdMeshSkeleton> Skeleton(new StdMeshSkeleton);
// First chunk must be the header
chunk.reset(Ogre::Skeleton::Chunk::Read(&stream));
chunk = Ogre::Skeleton::Chunk::Read(&stream);
if (chunk->GetType() != Ogre::Skeleton::CID_Header)
throw Ogre::Skeleton::InvalidVersion();
boost::ptr_map<uint16_t, StdMeshBone> bones;
boost::ptr_vector<Ogre::Skeleton::ChunkAnimation> animations;
std::map<uint16_t, std::unique_ptr<StdMeshBone>> bones;
unique_ptr_vector<Ogre::Skeleton::ChunkAnimation> animations;
for (Ogre::Skeleton::ChunkID id = Ogre::Skeleton::Chunk::Peek(&stream);
id == Ogre::Skeleton::CID_BlendMode || id == Ogre::Skeleton::CID_Bone || id == Ogre::Skeleton::CID_Bone_Parent || id == Ogre::Skeleton::CID_Animation;
id = Ogre::Skeleton::Chunk::Peek(&stream)
@ -340,7 +339,7 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
// Check that the bone ID is unique
if (bones.find(cbone.handle) != bones.end())
throw Ogre::Skeleton::IdNotUnique();
StdMeshBone *bone = new StdMeshBone;
auto bone = std::make_unique<StdMeshBone>();
bone->Parent = NULL;
bone->ID = cbone.handle;
bone->Name = cbone.name.c_str();
@ -348,7 +347,7 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
bone->Transformation.rotate = cbone.orientation;
bone->Transformation.scale = cbone.scale;
bone->InverseTransformation = StdMeshTransformation::Inverse(bone->Transformation);
bones.insert(cbone.handle, bone);
bones.insert(std::make_pair(cbone.handle, std::move(bone)));
}
break;
case Ogre::Skeleton::CID_Bone_Parent:
@ -356,13 +355,13 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
Ogre::Skeleton::ChunkBoneParent &cbparent = *static_cast<Ogre::Skeleton::ChunkBoneParent*>(chunk.get());
if (bones.find(cbparent.parentHandle) == bones.end() || bones.find(cbparent.childHandle) == bones.end())
throw Ogre::Skeleton::BoneNotFound();
bones[cbparent.parentHandle].Children.push_back(&bones[cbparent.childHandle]);
bones[cbparent.childHandle].Parent = &bones[cbparent.parentHandle];
bones[cbparent.parentHandle]->Children.push_back(bones[cbparent.childHandle].get());
bones[cbparent.childHandle]->Parent = bones[cbparent.parentHandle].get();
}
break;
case Ogre::Skeleton::CID_Animation:
// Collect animations for later (need bone table index, which we don't know yet)
animations.push_back(static_cast<Ogre::Skeleton::ChunkAnimation*>(chunk.release()));
animations.emplace_back(static_cast<Ogre::Skeleton::ChunkAnimation*>(chunk.release()));
break;
default:
assert(!"Unexpected enum value");
@ -373,19 +372,20 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
// Find master bone (i.e., the one without a parent)
StdMeshBone *master = NULL;
for (boost::ptr_map<uint16_t, StdMeshBone>::iterator it = bones.begin(); it != bones.end(); ++it)
for (auto& b: bones)
{
if (!it->second->Parent)
if (!b.second->Parent)
{
master = it->second;
master = b.second.get();
Skeleton->AddMasterBone(master);
}
}
if (!master)
throw Ogre::Skeleton::MissingMasterBone();
// Transfer bone ownership to mesh (double .release() is correct)
while (!bones.empty()) bones.release(bones.begin()).release();
// Transfer bone ownership to mesh
for (auto& b: bones) b.second.release();
bones.clear();
// Build handle->index quick access table
std::map<uint16_t, size_t> handle_lookup;
@ -395,34 +395,34 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
}
// Fixup animations
BOOST_FOREACH(Ogre::Skeleton::ChunkAnimation &canim, animations)
for(auto &canim: animations)
{
StdMeshAnimation &anim = Skeleton->Animations[StdCopyStrBuf(canim.name.c_str())];
anim.Name = canim.name.c_str();
anim.Length = canim.duration;
StdMeshAnimation &anim = Skeleton->Animations[StdCopyStrBuf(canim->name.c_str())];
anim.Name = canim->name.c_str();
anim.Length = canim->duration;
anim.Tracks.resize(Skeleton->GetNumBones());
anim.OriginSkeleton = &(*Skeleton);
BOOST_FOREACH(Ogre::Skeleton::ChunkAnimationTrack &catrack, canim.tracks)
for(auto &catrack: canim->tracks)
{
const StdMeshBone &bone = Skeleton->GetBone(handle_lookup[catrack.bone]);
const StdMeshBone &bone = Skeleton->GetBone(handle_lookup[catrack->bone]);
StdMeshTrack *&track = anim.Tracks[bone.Index];
if (track != NULL)
throw Ogre::Skeleton::MultipleBoneTracks();
track = new StdMeshTrack;
BOOST_FOREACH(Ogre::Skeleton::ChunkAnimationTrackKF &catkf, catrack.keyframes)
for(auto &catkf: catrack->keyframes)
{
StdMeshKeyFrame &kf = track->Frames[catkf.time];
kf.Transformation.rotate = catkf.rotation;
kf.Transformation.scale = catkf.scale;
kf.Transformation.translate = bone.InverseTransformation.rotate * (bone.InverseTransformation.scale * catkf.translation);
StdMeshKeyFrame &kf = track->Frames[catkf->time];
kf.Transformation.rotate = catkf->rotation;
kf.Transformation.scale = catkf->scale;
kf.Transformation.translate = bone.InverseTransformation.rotate * (bone.InverseTransformation.scale * catkf->translation);
kf.Transformation = OgreToClonk::TransformTransformation(kf.Transformation);
}
}
}
// Fixup bone transforms
BOOST_FOREACH(StdMeshBone *bone, Skeleton->Bones)
for(StdMeshBone *bone: Skeleton->Bones)
{
if (bone->Parent)
bone->Transformation = bone->Parent->Transformation * OgreToClonk::TransformTransformation(bone->Transformation);
@ -437,16 +437,16 @@ void StdMeshSkeletonLoader::LoadSkeletonBinary(const char* groupname, const char
StdMesh *StdMeshLoader::LoadMeshBinary(const char *sourcefile, size_t length, const StdMeshMatManager &mat_mgr, StdMeshSkeletonLoader &loader, const char *filename)
{
boost::scoped_ptr<Ogre::Mesh::Chunk> root;
std::unique_ptr<Ogre::Mesh::Chunk> root;
Ogre::DataStream stream(sourcefile, length);
// First chunk must be the header
root.reset(Ogre::Mesh::Chunk::Read(&stream));
root = Ogre::Mesh::Chunk::Read(&stream);
if (root->GetType() != Ogre::Mesh::CID_Header)
throw Ogre::Mesh::InvalidVersion();
// Second chunk is the mesh itself
root.reset(Ogre::Mesh::Chunk::Read(&stream));
root = Ogre::Mesh::Chunk::Read(&stream);
if (root->GetType() != Ogre::Mesh::CID_Mesh)
throw Ogre::Mesh::InvalidVersion();
@ -489,7 +489,7 @@ StdMesh *StdMeshLoader::LoadMeshBinary(const char *sourcefile, size_t length, co
{
mesh->SubMeshes.push_back(StdSubMesh());
StdSubMesh &sm = mesh->SubMeshes.back();
Ogre::Mesh::ChunkSubmesh &csm = cmesh.submeshes[i];
Ogre::Mesh::ChunkSubmesh &csm = *cmesh.submeshes[i];
sm.Material = mat_mgr.GetMaterial(csm.material.c_str());
if (!sm.Material)
throw Ogre::Mesh::InvalidMaterial();

View File

@ -17,25 +17,33 @@
#include "StdMeshLoaderBinaryChunks.h"
#include "StdMeshLoaderDataStream.h"
#include <cassert>
#include <boost/static_assert.hpp>
#include <boost/assign/list_of.hpp>
#include <string>
#include <utility>
// deleter-agnostic unique_ptr static caster
template<typename To, typename From>
std::unique_ptr<To> static_unique_cast(From&& p) {
return std::unique_ptr<To>(static_cast<To*>(p.release()));
}
using std::move;
namespace Ogre
{
namespace Mesh
{
const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor
const std::map<std::string, uint32_t> ChunkFileHeader::VersionTable = boost::assign::map_list_of
const std::map<std::string, uint32_t> ChunkFileHeader::VersionTable = {
// 1.8: Current version
("[MeshSerializer_v1.8]", CurrentVersion)
std::make_pair("[MeshSerializer_v1.8]", CurrentVersion),
// 1.41: Changes to morph keyframes and poses. We don't use either, so no special handling needed
("[MeshSerializer_v1.41]", 1041)
std::make_pair("[MeshSerializer_v1.41]", 1041),
// 1.40: Changes to CID_Mesh_LOD chunks, we ignore those, so no special handling needed
("[MeshSerializer_v1.40]", 1040);
std::make_pair("[MeshSerializer_v1.40]", 1040)
};
// Chunk factory
Chunk *Chunk::Read(DataStream *stream)
std::unique_ptr<Chunk> Chunk::Read(DataStream *stream)
{
assert(stream->GetRemainingBytes() >= ChunkHeaderLength);
@ -79,7 +87,7 @@ namespace Ogre
chunk->type = id;
chunk->size = size;
chunk->ReadImpl(stream);
return chunk.release();
return move(chunk);
}
void ChunkUnknown::ReadImpl(DataStream *stream) { stream->Seek(GetSize()); }
@ -100,40 +108,31 @@ namespace Ogre
id = Chunk::Peek(stream)
)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
switch (chunk->GetType())
{
case CID_Geometry:
if (geometry)
{
delete chunk;
throw MultipleSingletonChunks("There's only one CID_Geometry chunk allowed within a CID_Mesh chunk");
}
geometry.reset(static_cast<ChunkGeometry*>(chunk));
geometry = static_unique_cast<ChunkGeometry>(move(chunk));
break;
case CID_Submesh:
submeshes.push_back(static_cast<ChunkSubmesh*>(chunk));
submeshes.push_back(static_unique_cast<ChunkSubmesh>(move(chunk)));
break;
case CID_Mesh_Skeleton_Link:
if (!skeletonFile.empty())
{
delete chunk;
throw MultipleSingletonChunks("There's only one CID_Mesh_Skeleton_Link chunk allowed within a CID_Mesh chunk");
}
skeletonFile = static_cast<ChunkMeshSkeletonLink*>(chunk)->skeleton;
delete chunk;
skeletonFile = static_cast<ChunkMeshSkeletonLink*>(chunk.get())->skeleton;
break;
case CID_Mesh_Bounds:
bounds = static_cast<ChunkMeshBounds*>(chunk)->bounds;
radius = static_cast<ChunkMeshBounds*>(chunk)->radius;
delete chunk;
bounds = static_cast<ChunkMeshBounds*>(chunk.get())->bounds;
radius = static_cast<ChunkMeshBounds*>(chunk.get())->radius;
break;
case CID_Mesh_Bone_Assignment:
// Collect bone assignments
{
ChunkMeshBoneAssignments *assignments = static_cast<ChunkMeshBoneAssignments*>(chunk);
ChunkMeshBoneAssignments *assignments = static_cast<ChunkMeshBoneAssignments*>(chunk.get());
boneAssignments.insert(boneAssignments.end(), assignments->assignments.begin(), assignments->assignments.end());
delete chunk;
break;
}
default:
@ -142,7 +141,6 @@ namespace Ogre
case CID_Submesh_Name_Table:
case CID_Edge_List:
// Ignore those
delete chunk;
break;
}
if (stream->AtEof()) break;
@ -176,39 +174,30 @@ namespace Ogre
id = Chunk::Peek(stream)
)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
switch (chunk->GetType())
{
case CID_Geometry:
if (hasSharedVertices)
{
// Can't have own vertices and at the same time use those of the parent
delete chunk;
throw SharedVertexGeometryForbidden();
}
if (geometry)
{
delete chunk;
throw MultipleSingletonChunks("There's only one CID_Geometry chunk allowed within a CID_Submesh chunk");
}
geometry.reset(static_cast<ChunkGeometry*>(chunk));
geometry = static_unique_cast<ChunkGeometry>(move(chunk));
break;
case CID_Submesh_Op:
operation = static_cast<ChunkSubmeshOp*>(chunk)->operation;
delete chunk;
operation = static_cast<ChunkSubmeshOp*>(chunk.get())->operation;
break;
case CID_Submesh_Bone_Assignment:
{
// Collect bone assignments
ChunkMeshBoneAssignments *assignments = static_cast<ChunkMeshBoneAssignments*>(chunk);
ChunkMeshBoneAssignments *assignments = static_cast<ChunkMeshBoneAssignments*>(chunk.get());
boneAssignments.insert(boneAssignments.end(), assignments->assignments.begin(), assignments->assignments.end());
}
delete chunk;
break;
default:
LogF("StdMeshLoader: I don't know what to do with a chunk of type 0x%xu inside a CID_Submesh chunk", chunk->GetType());
delete chunk;
break;
}
if (stream->AtEof()) break;
@ -255,25 +244,20 @@ namespace Ogre
id = Chunk::Peek(stream)
)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
switch (chunk->GetType())
{
case CID_Geometry_Vertex_Decl:
if (!vertexDeclaration.empty())
{
delete chunk;
throw MultipleSingletonChunks("There's only one CID_Geometry_Vertex_Decl chunk allowed within a CID_Geometry chunk");
}
vertexDeclaration.swap(static_cast<ChunkGeometryVertexDecl*>(chunk)->declaration);
delete chunk;
vertexDeclaration.swap(static_cast<ChunkGeometryVertexDecl*>(chunk.get())->declaration);
break;
case CID_Geometry_Vertex_Buffer:
vertexBuffers.push_back(static_cast<ChunkGeometryVertexBuffer*>(chunk));
vertexBuffers.push_back(static_unique_cast<ChunkGeometryVertexBuffer>(move(chunk)));
break;
default:
LogF("StdMeshLoader: I don't know what to do with a chunk of type 0x%xu inside a CID_Geometry chunk", chunk->GetType());
delete chunk;
break;
}
if (stream->AtEof()) break;
@ -284,9 +268,9 @@ namespace Ogre
{
while (Chunk::Peek(stream) == CID_Geometry_Vertex_Decl_Element)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
assert(chunk->GetType() == CID_Geometry_Vertex_Decl_Element);
declaration.push_back(static_cast<ChunkGeometryVertexDeclElement*>(chunk));
declaration.push_back(static_unique_cast<ChunkGeometryVertexDeclElement>(chunk));
if (stream->AtEof()) break;
}
}
@ -313,14 +297,11 @@ namespace Ogre
while (Chunk::Peek(stream) == CID_Geometry_Vertex_Data)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
assert(chunk->GetType() == CID_Geometry_Vertex_Data);
if (data)
{
delete chunk;
throw MultipleSingletonChunks("There's only one CID_Geometry_Vertex_Data chunk allowed within a CID_Geometry_Vertex_Buffer chunk");
}
data.reset(static_cast<ChunkGeometryVertexData*>(chunk));
data = static_unique_cast<ChunkGeometryVertexData>(move(chunk));
if (stream->AtEof()) break;
}
}
@ -335,13 +316,14 @@ namespace Ogre
namespace Skeleton
{
const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor
const std::map<std::string, uint32_t> ChunkFileHeader::VersionTable = boost::assign::map_list_of
const std::map<std::string, uint32_t> ChunkFileHeader::VersionTable = {
// 1.80: Current version
("[Serializer_v1.80]", CurrentVersion)
std::make_pair("[Serializer_v1.80]", CurrentVersion),
// 1.10: adds SKELETON_BLENDMODE and SKELETON_ANIMATION_BASEINFO chunks. The chunks have been added to the loader, but we ignore them for now.
("[Serializer_v1.10]", 1010);
std::make_pair("[Serializer_v1.10]", 1010)
};
Chunk *Chunk::Read(DataStream *stream)
std::unique_ptr<Chunk> Chunk::Read(DataStream *stream)
{
assert(stream->GetRemainingBytes() >= ChunkHeaderLength);
@ -377,7 +359,7 @@ namespace Ogre
chunk->type = id;
chunk->size = size;
chunk->ReadImpl(stream);
return chunk.release();
return chunk;
}
void ChunkUnknown::ReadImpl(DataStream *stream) { stream->Seek(GetSize()); }
@ -432,18 +414,17 @@ namespace Ogre
if(!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_BaseInfo)
{
Chunk* chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
assert(chunk->GetType() == CID_Animation_BaseInfo);
// TODO: Handle it
LogF("StdMeshLoader: CID_Animation_BaseInfo not implemented. Skeleton might not be imported properly.");
delete chunk;
}
while (!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_Track)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
assert(chunk->GetType() == CID_Animation_Track);
tracks.push_back(static_cast<ChunkAnimationTrack*>(chunk));
tracks.push_back(static_unique_cast<ChunkAnimationTrack>(move(chunk)));
}
}
@ -458,9 +439,9 @@ namespace Ogre
bone = stream->Read<uint16_t>();
while (Chunk::Peek(stream) == CID_Animation_Track_KF)
{
Chunk *chunk = Chunk::Read(stream);
std::unique_ptr<Chunk> chunk = Chunk::Read(stream);
assert(chunk->GetType() == CID_Animation_Track_KF);
keyframes.push_back(static_cast<ChunkAnimationTrackKF*>(chunk));
keyframes.push_back(static_unique_cast<ChunkAnimationTrackKF>(move(chunk)));
if (stream->AtEof()) break;
}
}

View File

@ -19,10 +19,6 @@
#include "StdMesh.h"
#include "StdMeshLoaderDataStream.h"
#include <boost/scoped_ptr.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/static_assert.hpp>
// ==== Ogre file format ====
// The Ogre file format is a chunked format similar to PNG.
// Each chunk except for the file header (type 0x1000) has the following format:
@ -276,6 +272,10 @@
// Most of the chunk classes below faithfully match the abovementioned file format.
namespace Ogre
{
// used to have boost::ptr_vector. Behaves reasonably similar
template<typename T>
using unique_ptr_vector = std::vector<std::unique_ptr<T>>;
class DataStream;
template<class _Type>
class ChunkBase
@ -348,7 +348,7 @@ namespace Ogre
class Chunk : public ChunkBase<ChunkID>
{
public:
static Chunk *Read(DataStream *stream);
static std::unique_ptr<Chunk> Read(DataStream *stream);
};
class ChunkUnknown; class
@ -384,8 +384,8 @@ namespace Ogre
ChunkMesh() : hasAnimatedSkeleton(false), radius(0.0f) {}
bool hasAnimatedSkeleton;
std::string skeletonFile;
boost::scoped_ptr<ChunkGeometry> geometry;
boost::ptr_vector<ChunkSubmesh> submeshes;
std::unique_ptr<ChunkGeometry> geometry;
unique_ptr_vector<ChunkSubmesh> submeshes;
std::vector<BoneAssignment> boneAssignments;
StdMeshBox bounds;
float radius;
@ -409,7 +409,7 @@ namespace Ogre
std::string material;
bool hasSharedVertices;
std::vector<size_t> faceVertices;
boost::scoped_ptr<ChunkGeometry> geometry;
std::unique_ptr<ChunkGeometry> geometry;
enum SubmeshOperation
{
SO_PointList = 1,
@ -455,8 +455,8 @@ namespace Ogre
{
public:
size_t vertexCount;
boost::ptr_vector<ChunkGeometryVertexDeclElement> vertexDeclaration;
boost::ptr_vector<ChunkGeometryVertexBuffer> vertexBuffers;
unique_ptr_vector<ChunkGeometryVertexDeclElement> vertexDeclaration;
unique_ptr_vector<ChunkGeometryVertexBuffer> vertexBuffers;
protected:
virtual void ReadImpl(DataStream *stream);
};
@ -464,7 +464,7 @@ namespace Ogre
class ChunkGeometryVertexDecl : public Chunk
{
public:
boost::ptr_vector<ChunkGeometryVertexDeclElement> declaration;
unique_ptr_vector<ChunkGeometryVertexDeclElement> declaration;
protected:
virtual void ReadImpl(DataStream *stream);
};
@ -515,7 +515,7 @@ namespace Ogre
public:
uint16_t index;
uint16_t vertexSize;
boost::scoped_ptr<ChunkGeometryVertexData> data;
std::unique_ptr<ChunkGeometryVertexData> data;
protected:
void ReadImpl(DataStream *stream);
};
@ -550,7 +550,7 @@ namespace Ogre
class Chunk : public ChunkBase<ChunkID>
{
public:
static Chunk *Read(DataStream *stream);
static std::unique_ptr<Chunk> Read(DataStream *stream);
};
class ChunkUnknown; class ChunkFileHeader;
@ -610,7 +610,7 @@ namespace Ogre
public:
std::string name;
float duration;
boost::ptr_vector<ChunkAnimationTrack> tracks;
unique_ptr_vector<ChunkAnimationTrack> tracks;
protected:
virtual void ReadImpl(DataStream *stream);
};
@ -628,7 +628,7 @@ namespace Ogre
{
public:
uint16_t bone;
boost::ptr_vector<ChunkAnimationTrackKF> keyframes;
unique_ptr_vector<ChunkAnimationTrackKF> keyframes;
protected:
virtual void ReadImpl(DataStream *stream);
};

View File

@ -17,13 +17,10 @@
#define INC_StdMeshLoaderDataStream
#include "StdMeshLoader.h"
#include <boost/noncopyable.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
namespace Ogre
{
class DataStream : boost::noncopyable
class DataStream
{
const char *begin, *cursor, *end;
public:
@ -33,6 +30,10 @@ namespace Ogre
end = cursor + length;
}
// non-copyable
DataStream(const DataStream&) = delete;
DataStream& operator=(const DataStream&) = delete;
bool AtEof() const { return cursor == end; }
size_t GetRemainingBytes() const { return end - cursor; }
void Rewind() { cursor = begin; }
@ -47,8 +48,7 @@ namespace Ogre
// Only read directly into T when T is trivially copyable (i.e., allows bit-wise copy)
template<class T>
typename boost::enable_if<boost::has_trivial_copy<T>,
typename boost::disable_if<boost::is_pointer<T>, T>::type>::type
typename std::enable_if<std::is_pod<T>::value && !std::is_pointer<T>::value, T>::type
Peek() const
{
if (GetRemainingBytes() < sizeof(T))
@ -59,7 +59,7 @@ namespace Ogre
}
// declaration for non-trivially copyable types
template<class T> typename boost::disable_if<boost::has_trivial_copy<T>, T>::type
template<class T> typename std::enable_if<!std::is_pod<T>::value, T>::type
Peek() const;
template<class T> T Read()

View File

@ -18,9 +18,6 @@
#include "C4Application.h"
#include "C4Log.h"
#include <boost/function.hpp>
#include <boost/scoped_ptr.hpp>
#include <C4Game.h>
// *** C4InteractiveThread
@ -153,7 +150,7 @@ void C4InteractiveThread::ProcessEvents() // by main thread
case Ev_Function:
{
boost::scoped_ptr<boost::function<void ()> > func(static_cast<boost::function<void()>*>(pEventData));
std::unique_ptr<std::function<void ()> > func(static_cast<std::function<void()>*>(pEventData));
(*func)();
}

View File

@ -18,7 +18,6 @@
#include "StdScheduler.h"
#include "StdSync.h"
#include <boost/function.hpp>
// Event types
enum C4InteractiveEventType
@ -114,7 +113,7 @@ public:
template<typename Functor>
bool ThreadPostAsync(Functor function)
{
return PushEvent(Ev_Function, new boost::function<void ()>(function));
return PushEvent(Ev_Function, new std::function<void ()>(function));
}
// event handlers

View File

@ -400,7 +400,7 @@ bool C4Network2IRCClient::Join(const char *szChannel)
const char* message = LoadResStr("IDS_ERR_CHANNELNOTALLOWED");
PushMessage(MSG_Status, "", "", message);
SetError("Joining this channel not allowed");
Application.InteractiveThread.ThreadPostAsync(boost::bind(&C4GUI::Screen::ShowMessage, ::pGUI, message, LoadResStr("IDS_DLG_CHAT"), C4GUI::Ico_Error, static_cast<int32_t* const &>(0)));
Application.InteractiveThread.ThreadPostAsync(std::bind(&C4GUI::Screen::ShowMessage, ::pGUI, message, LoadResStr("IDS_DLG_CHAT"), C4GUI::Ico_Error, static_cast<int32_t* const &>(0)));
return false;
}
return Send("JOIN", szChannel);

View File

@ -18,13 +18,15 @@
#define INC_C4Network2Upnp
#include "network/C4Network2IO.h"
#include <boost/noncopyable.hpp>
class C4Network2UPnP : boost::noncopyable
class C4Network2UPnP
{
struct C4Network2UPnPP *p;
public:
C4Network2UPnP();
//noncopyable
C4Network2UPnP(const C4Network2UPnP&) = delete;
C4Network2UPnP& operator=(const C4Network2UPnP&) = delete;
~C4Network2UPnP();
void AddMapping(enum C4Network2IOProtocol protocol, uint16_t intport, uint16_t extport);

View File

@ -19,8 +19,6 @@
#include "network/C4Network2UPnP.h"
#include "C4Version.h"
#include <boost/foreach.hpp>
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
@ -124,7 +122,7 @@ void C4Network2UPnPP::ClearNatMappings()
{
if (!mappings)
return;
BOOST_FOREACH(IStaticPortMapping *mapping, added_mappings)
for(IStaticPortMapping *mapping: added_mappings)
{
BSTR proto, client;
long intport, extport;

View File

@ -92,14 +92,6 @@ typedef ptrdiff_t ssize_t;
#endif
#ifndef HAVE_STATIC_ASSERT
#include <boost/static_assert.hpp>
#ifndef BOOST_HAS_STATIC_ASSERT
#define static_assert(x, y) BOOST_STATIC_ASSERT(x)
#endif
#endif
// std::make_unique
#include "platform/make_unique.h"

View File

@ -23,6 +23,7 @@
#include <utility>
#ifndef HAVE_MAKE_UNIQUE
namespace detail {
template<class T>
typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, std::unique_ptr<T>>::type
make_unique(size_t n)
@ -30,41 +31,13 @@ make_unique(size_t n)
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
}
#ifdef HAVE_VARIADIC_TEMPLATES
template<class T, class ...Args>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(Args &&...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#else
// We have to emulate variadic templates with preprocessor trickery.
// Create a number of overloaded functions that handle this just like the
// one function above. Works for up to _VARIADIC_MAX constructor arguments
// (if you need more than 5, define that macro before including this header).
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
// This is the same macro that the MSVC STL also uses when it has to emulate
// variadic templates, so it should work fine for our purposes
#ifndef _VARIADIC_MAX
#define _VARIADIC_MAX 5
#endif
#define MAKE_UNIQUE_FORWARDER(z, n, unused) std::forward<Arg ## n>(arg ## n)
#define MAKE_UNIQUE_MAKER(z, n, unused) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class Arg)> \
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type make_unique(BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, &&arg)) \
{ \
return std::unique_ptr<T>(new T(BOOST_PP_ENUM(n, MAKE_UNIQUE_FORWARDER, unused))); \
}
BOOST_PP_REPEAT(BOOST_PP_INC(_VARIADIC_MAX), MAKE_UNIQUE_MAKER, unused)
#undef MAKE_UNIQUE_MAKER
#undef MAKE_UNIQUE_FORWARDER
#endif
}
namespace std { using ::detail::make_unique; }
#endif