From 82f3574d09064a442e30eb2dc7639f473749c5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 3 Dec 2014 11:27:24 +0100 Subject: [PATCH] add array overloads to make_unique and move it to mbgl::util from std --- include/mbgl/platform/log.hpp | 4 ++- include/mbgl/util/std.hpp | 35 ++++++++++++++------ platform/darwin/http_request_baton_cocoa.mm | 6 ++-- platform/darwin/image.mm | 3 +- platform/default/headless_view.cpp | 6 ++-- platform/default/http_request_baton_curl.cpp | 5 +-- platform/default/image.cpp | 3 +- platform/default/image_reader.cpp | 4 +-- src/map/map.cpp | 12 +++---- src/map/source.cpp | 2 +- src/map/sprite.cpp | 2 +- src/map/tile_parser.cpp | 10 +++--- src/renderer/painter.cpp | 24 +++++++------- src/storage/base_request.cpp | 3 +- src/storage/file_request_baton.cpp | 7 ++-- src/storage/file_source.cpp | 3 +- src/storage/sqlite_store.cpp | 3 +- src/style/style.cpp | 2 +- src/style/style_parser.cpp | 2 +- src/text/glyph_store.cpp | 4 +-- src/util/raster.cpp | 2 +- 21 files changed, 84 insertions(+), 58 deletions(-) diff --git a/include/mbgl/platform/log.hpp b/include/mbgl/platform/log.hpp index 406b3eea3..418160d3e 100644 --- a/include/mbgl/platform/log.hpp +++ b/include/mbgl/platform/log.hpp @@ -3,6 +3,8 @@ #include "event.hpp" +#include + #include #include @@ -58,7 +60,7 @@ public: template static inline const T &Set(Args&& ...args) { - Backend = ::std::unique_ptr(new T(::std::forward(args)...)); + Backend = util::make_unique(::std::forward(args)...); return *dynamic_cast(Backend.get()); } diff --git a/include/mbgl/util/std.hpp b/include/mbgl/util/std.hpp index 051f89bb6..e64820de4 100644 --- a/include/mbgl/util/std.hpp +++ b/include/mbgl/util/std.hpp @@ -2,20 +2,35 @@ #define MBGL_UTIL_STD #include - -namespace std { - -// C++14 backfill from http://herbsutter.com/gotw/_102/ -template -::std::unique_ptr make_unique(Args&& ...args) { - return ::std::unique_ptr(new T(::std::forward(args)...)); -} - -} +#include +#include namespace mbgl { namespace util { +// C++14 backfill based on http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory + +namespace detail { +template struct unique_type { typedef ::std::unique_ptr single; }; +template struct unique_type { typedef ::std::unique_ptr unknown_bound; }; +template struct unique_type { typedef void known_bound; }; +} + +template +typename detail::unique_type::single make_unique(Args&&... args) { + return ::std::unique_ptr(new T(::std::forward(args)...)); +} + +template +typename detail::unique_type::unknown_bound make_unique(size_t size) { + return ::std::unique_ptr(new typename ::std::remove_extent::type[size]()); +} + +template +typename detail::unique_type::known_bound make_unique(Args&&...) = delete; + + + template void erase_if(Container &container, ForwardIterator it, const ForwardIterator end, Predicate pred) { while (it != end) { diff --git a/platform/darwin/http_request_baton_cocoa.mm b/platform/darwin/http_request_baton_cocoa.mm index 03fa3bb82..28afbb508 100644 --- a/platform/darwin/http_request_baton_cocoa.mm +++ b/platform/darwin/http_request_baton_cocoa.mm @@ -51,7 +51,7 @@ void HTTPRequestBaton::start(const util::ptr &ptr) { } else { // TODO: Use different codes for host not found, timeout, invalid URL etc. // These can be categorized in temporary and permanent errors. - baton->response = std::make_unique(); + baton->response = util::make_unique(); baton->response->code = [(NSHTTPURLResponse *)res statusCode]; baton->response->message = [[error localizedDescription] UTF8String]; @@ -86,7 +86,7 @@ void HTTPRequestBaton::start(const util::ptr &ptr) { // Assume a Response object already exists. assert(baton->response); } else { - baton->response = std::make_unique(); + baton->response = util::make_unique(); baton->response->code = code; baton->response->data = {(const char *)[data bytes], [data length]}; } @@ -117,7 +117,7 @@ void HTTPRequestBaton::start(const util::ptr &ptr) { } else { // This should never happen. baton->type = HTTPResponseType::PermanentError; - baton->response = std::make_unique(); + baton->response = util::make_unique(); baton->response->code = -1; baton->response->message = "response class is not NSHTTPURLResponse"; } diff --git a/platform/darwin/image.mm b/platform/darwin/image.mm index b8df3c403..4819d2cd3 100644 --- a/platform/darwin/image.mm +++ b/platform/darwin/image.mm @@ -1,4 +1,5 @@ #include +#include #import @@ -97,7 +98,7 @@ Image::Image(const std::string &source_data) { height = uint32_t(CGImageGetHeight(image)); CGRect rect = {{ 0, 0 }, { static_cast(width), static_cast(height) }}; - img = ::std::unique_ptr(new char[width * height * 4]()); + img = util::make_unique(width * height * 4); CGContextRef context = CGBitmapContextCreate(img.get(), width, height, 8, width * 4, color_space, kCGImageAlphaPremultipliedLast); if (!context) { diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp index 10d6ed8f4..5b95c7602 100644 --- a/platform/default/headless_view.cpp +++ b/platform/default/headless_view.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include #include #include @@ -232,14 +234,14 @@ std::unique_ptr HeadlessView::readPixels() { const unsigned int w = width_ * pixelRatio_; const unsigned int h = height_ * pixelRatio_; - auto pixels = std::unique_ptr(new uint32_t[w * h]); + auto pixels = util::make_unique(w * h); make_active(); glReadPixels(0, 0, width_, height_, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); make_inactive(); const int stride = w * 4; - auto tmp = std::unique_ptr(new char[stride]()); + auto tmp = util::make_unique(stride); char *rgba = reinterpret_cast(pixels.get()); for (int i = 0, j = height_ - 1; i < j; i++, j--) { std::memcpy(tmp.get(), rgba + i * stride, stride); diff --git a/platform/default/http_request_baton_curl.cpp b/platform/default/http_request_baton_curl.cpp index 02e9497c9..4b825622a 100644 --- a/platform/default/http_request_baton_curl.cpp +++ b/platform/default/http_request_baton_curl.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -114,7 +115,7 @@ struct Context { CURLMcode error = curl_multi_remove_handle(multi, handle); if (error != CURLM_OK) { - baton->response = std::unique_ptr(new Response()); + baton->response = util::make_unique(); baton->response->code = -1; baton->response->message = curl_multi_strerror(error); } @@ -429,7 +430,7 @@ void start_request(void *const ptr) { } if (!context->baton->response) { - context->baton->response = std::unique_ptr(new Response()); + context->baton->response = util::make_unique(); } // Carry on the shared pointer in the private information of the CURL handle. diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 242367e88..d881b9231 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -80,7 +81,7 @@ Image::Image(std::string const& data) auto reader = getImageReader(data.c_str(), data.size()); width = reader->width(); height = reader->height(); - img = ::std::unique_ptr(new char[width * height * 4]()); + img = util::make_unique(width * height * 4); reader->read(0, 0, width, height, img.get()); } catch (ImageReaderException const& ex) diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index e80ccb681..fc6daec6a 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -49,11 +49,11 @@ std::unique_ptr getImageReader(char const* data, size_t size) { if (*type == "png") { - return std::make_unique>(data, size); + return util::make_unique>(data, size); } else if (*type == "jpeg") { - return std::make_unique>(data, size); + return util::make_unique>(data, size); } } throw ImageReaderException("ImageReader: can't determine type from input data"); diff --git a/src/map/map.cpp b/src/map/map.cpp index b3c83d1be..cc22e048f 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -86,7 +86,7 @@ const static bool sqlite_version_check = []() { using namespace mbgl; Map::Map(View& view_) - : loop(std::make_unique()), + : loop(util::make_unique()), view(view_), #ifndef NDEBUG mainThread(uv_thread_self()), @@ -123,7 +123,7 @@ Map::~Map() { uv::worker &Map::getWorker() { if (!workers) { - workers = std::make_unique(**loop, 4, "Tile Worker"); + workers = util::make_unique(**loop, 4, "Tile Worker"); } return *workers; } @@ -140,7 +140,7 @@ void Map::start() { isStopped = false; // Setup async notifications - asyncTerminate = std::make_unique(**loop, [this]() { + asyncTerminate = util::make_unique(**loop, [this]() { assert(uv_thread_self() == mapThread); // Remove all of these to make sure they are destructed in the correct thread. @@ -156,7 +156,7 @@ void Map::start() { asyncTerminate.reset(); }); - asyncRender = std::make_unique(**loop, [this]() { + asyncRender = util::make_unique(**loop, [this]() { assert(uv_thread_self() == mapThread); if (state.hasSize()) { @@ -175,11 +175,11 @@ void Map::start() { } }); - asyncCleanup = std::make_unique(**loop, [this]() { + asyncCleanup = util::make_unique(**loop, [this]() { painter.cleanup(); }); - thread = std::make_unique([this]() { + thread = util::make_unique([this]() { #ifndef NDEBUG mapThread = uv_thread_self(); #endif diff --git a/src/map/source.cpp b/src/map/source.cpp index 8737e3875..35f507286 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -164,7 +164,7 @@ TileData::State Source::addTile(Map& map, uv::worker& worker, return state; } - auto pos = tiles.emplace(id, std::make_unique(id)); + auto pos = tiles.emplace(id, util::make_unique(id)); Tile& new_tile = *pos.first->second; // We couldn't find the tile in the list. Create a new one. diff --git a/src/map/sprite.cpp b/src/map/sprite.cpp index 82073619d..c1f71e59d 100644 --- a/src/map/sprite.cpp +++ b/src/map/sprite.cpp @@ -101,7 +101,7 @@ bool Sprite::isLoaded() const { } void Sprite::parseImage() { - raster = std::make_unique(image); + raster = util::make_unique(image); if (!*raster) { raster.reset(); } diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index 8f5532678..cbfd6fa7b 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -44,7 +44,7 @@ TileParser::TileParser(const std::string &data, VectorTileData &tile_, spriteAtlas(spriteAtlas_), sprite(sprite_), texturePool(texturePool_), - collision(std::make_unique(tile.id.z, 4096, tile.source.tile_size, tile.depth)) { + collision(util::make_unique(tile.id.z, 4096, tile.source.tile_size, tile.depth)) { assert(&tile != nullptr); assert(style); assert(sprite); @@ -150,24 +150,24 @@ void TileParser::addBucketGeometries(Bucket& bucket, const VectorTileLayer& laye } std::unique_ptr TileParser::createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill) { - std::unique_ptr bucket = std::make_unique(tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, fill); + std::unique_ptr bucket = util::make_unique(tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, fill); addBucketGeometries(bucket, layer, filter); return obsolete() ? nullptr : std::move(bucket); } std::unique_ptr TileParser::createRasterBucket(const StyleBucketRaster &raster) { - std::unique_ptr bucket = std::make_unique(texturePool, raster); + std::unique_ptr bucket = util::make_unique(texturePool, raster); return obsolete() ? nullptr : std::move(bucket); } std::unique_ptr TileParser::createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line) { - std::unique_ptr bucket = std::make_unique(tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, line); + std::unique_ptr bucket = util::make_unique(tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, line); addBucketGeometries(bucket, layer, filter); return obsolete() ? nullptr : std::move(bucket); } std::unique_ptr TileParser::createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol) { - std::unique_ptr bucket = std::make_unique(symbol, *collision); + std::unique_ptr bucket = util::make_unique(symbol, *collision); bucket->addFeatures(layer, filter, tile.id, spriteAtlas, *sprite, glyphAtlas, glyphStore); return obsolete() ? nullptr : std::move(bucket); } diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 3b4e817d3..15bf9e3a0 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -89,18 +89,18 @@ void Painter::setup() { } void Painter::setupShaders() { - if (!plainShader) plainShader = std::make_unique(); - if (!outlineShader) outlineShader = std::make_unique(); - if (!lineShader) lineShader = std::make_unique(); - if (!linejoinShader) linejoinShader = std::make_unique(); - if (!linepatternShader) linepatternShader = std::make_unique(); - if (!patternShader) patternShader = std::make_unique(); - if (!iconShader) iconShader = std::make_unique(); - if (!rasterShader) rasterShader = std::make_unique(); - if (!sdfGlyphShader) sdfGlyphShader = std::make_unique(); - if (!sdfIconShader) sdfIconShader = std::make_unique(); - if (!dotShader) dotShader = std::make_unique(); - if (!gaussianShader) gaussianShader = std::make_unique(); + if (!plainShader) plainShader = util::make_unique(); + if (!outlineShader) outlineShader = util::make_unique(); + if (!lineShader) lineShader = util::make_unique(); + if (!linejoinShader) linejoinShader = util::make_unique(); + if (!linepatternShader) linepatternShader = util::make_unique(); + if (!patternShader) patternShader = util::make_unique(); + if (!iconShader) iconShader = util::make_unique(); + if (!rasterShader) rasterShader = util::make_unique(); + if (!sdfGlyphShader) sdfGlyphShader = util::make_unique(); + if (!sdfIconShader) sdfIconShader = util::make_unique(); + if (!dotShader) dotShader = util::make_unique(); + if (!gaussianShader) gaussianShader = util::make_unique(); } void Painter::deleteShaders() { diff --git a/src/storage/base_request.cpp b/src/storage/base_request.cpp index e87679ae1..9819dc89f 100644 --- a/src/storage/base_request.cpp +++ b/src/storage/base_request.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -68,7 +69,7 @@ Callback *BaseRequest::add(Callback &&callback, const util::ptr &re return nullptr; } else { self = request; - callbacks.push_front(std::unique_ptr(new Callback(std::move(callback)))); + callbacks.push_front(util::make_unique(std::move(callback))); return callbacks.front().get(); } } diff --git a/src/storage/file_request_baton.cpp b/src/storage/file_request_baton.cpp index 1b41a5370..75ea95df4 100644 --- a/src/storage/file_request_baton.cpp +++ b/src/storage/file_request_baton.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -29,7 +30,7 @@ void FileRequestBaton::notify_error(uv_fs_t *req) { assert(ptr->thread_id == uv_thread_self()); if (ptr->request && req->result < 0 && !ptr->canceled && req->result != UV_ECANCELED) { - ptr->request->response = std::unique_ptr(new Response); + ptr->request->response = util::make_unique(); ptr->request->response->code = req->result == UV_ENOENT ? 404 : 500; #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 ptr->request->response->message = uv_strerror(uv_last_error(req->loop)); @@ -86,7 +87,7 @@ void FileRequestBaton::file_stated(uv_fs_t *req) { // File is too large for us to open this way because uv_buf's only support unsigned // ints as maximum size. if (ptr->request) { - ptr->request->response = std::unique_ptr(new Response); + ptr->request->response = util::make_unique(); ptr->request->response->code = UV_EFBIG; #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 ptr->request->response->message = uv_strerror(uv_err_t {UV_EFBIG, 0}); @@ -123,7 +124,7 @@ void FileRequestBaton::file_read(uv_fs_t *req) { } else { // File was successfully read. if (ptr->request) { - ptr->request->response = std::unique_ptr(new Response); + ptr->request->response = util::make_unique(); ptr->request->response->code = 200; ptr->request->response->data = std::move(ptr->body); ptr->request->notify(); diff --git a/src/storage/file_source.cpp b/src/storage/file_source.cpp index a67f57dac..d1e4c8f38 100644 --- a/src/storage/file_source.cpp +++ b/src/storage/file_source.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -79,7 +80,7 @@ std::unique_ptr FileSource::request(ResourceType type, const std::strin pending.emplace(absoluteURL, req); } - return std::unique_ptr(new Request(req)); + return util::make_unique(req); } void FileSource::prepare(std::function fn) { diff --git a/src/storage/sqlite_store.cpp b/src/storage/sqlite_store.cpp index e0757ecc3..bc262e386 100644 --- a/src/storage/sqlite_store.cpp +++ b/src/storage/sqlite_store.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -127,7 +128,7 @@ void SQLiteStore::get(const std::string &path, GetCallback callback, void *ptr) stmt.bind(1, url.c_str()); if (stmt.run()) { // There is data. - baton->response = std::unique_ptr(new Response); + baton->response = util::make_unique(); baton->response->code = stmt.get(0); baton->type = ResourceType(stmt.get(1)); diff --git a/src/style/style.cpp b/src/style/style.cpp index 030c50208..15ca4e14f 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -17,7 +17,7 @@ namespace mbgl { Style::Style() - : mtx(std::make_unique()) { + : mtx(util::make_unique()) { } // Note: This constructor is seemingly empty, but we need to declare it anyway diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 22d43df44..2dec648af 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -449,7 +449,7 @@ bool StyleParser::parseOptionalProperty(const char *property_name, const std::ve std::unique_ptr StyleParser::createLayers(JSVal value) { if (value.IsArray()) { - std::unique_ptr group = std::make_unique(); + std::unique_ptr group = util::make_unique(); for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { util::ptr layer = createLayer(value[i]); if (layer) { diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp index 737bad35d..8537ab515 100644 --- a/src/text/glyph_store.cpp +++ b/src/text/glyph_store.cpp @@ -271,7 +271,7 @@ std::shared_future GlyphStore::loadGlyphRange(const std::string &fon auto range_it = rangeSets.find(range); if (range_it == rangeSets.end()) { // We don't have this glyph set yet for this font stack. - range_it = rangeSets.emplace(range, std::make_unique(glyphURL, fontStack, range, fileSource)).first; + range_it = rangeSets.emplace(range, util::make_unique(glyphURL, fontStack, range, fileSource)).first; } return range_it->second->getFuture(); @@ -280,7 +280,7 @@ std::shared_future GlyphStore::loadGlyphRange(const std::string &fon FontStack &GlyphStore::createFontStack(const std::string &fontStack) { auto stack_it = stacks.find(fontStack); if (stack_it == stacks.end()) { - stack_it = stacks.emplace(fontStack, std::make_unique()).first; + stack_it = stacks.emplace(fontStack, util::make_unique()).first; } return *stack_it->second.get(); } diff --git a/src/util/raster.cpp b/src/util/raster.cpp index 66c5c13fe..56461aec5 100644 --- a/src/util/raster.cpp +++ b/src/util/raster.cpp @@ -27,7 +27,7 @@ bool Raster::isLoaded() const { } bool Raster::load(const std::string &data) { - img = std::make_unique(data); + img = util::make_unique(data); width = img->getWidth(); height = img->getHeight();