/* * Copyright (c) 2011-2021, The DART development contributors * All rights reserved. * * The list of contributors can be found at: * https://github.com/dartsim/dart/blob/master/LICENSE * * This file is provided under the following "BSD-style" License: * 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. * 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 COPYRIGHT HOLDER 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. */ #ifndef DART_COMMON_DETAIL_SPECIALIZEDFORASPECT_HPP_ #define DART_COMMON_DETAIL_SPECIALIZEDFORASPECT_HPP_ #include "dart/common/SpecializedForAspect.hpp" // This preprocessor token should only be used by the unittest that is // responsible for checking that the specialized routines are being used to // access specialized Aspects #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS bool usedSpecializedAspectAccess; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS namespace dart { namespace common { //============================================================================== template SpecializedForAspect::SpecializedForAspect() { mSpecAspectIterator = mAspectMap .insert(std::make_pair>( typeid(SpecAspect), nullptr)) .first; } //============================================================================== template template bool SpecializedForAspect::has() const { return _has(type()); } //============================================================================== template template T* SpecializedForAspect::get() { return _get(type()); } //============================================================================== template template const T* SpecializedForAspect::get() const { return _get(type()); } //============================================================================== template template void SpecializedForAspect::set(const T* aspect) { _set(type(), aspect); } //============================================================================== template template void SpecializedForAspect::set(std::unique_ptr&& aspect) { _set(type(), std::move(aspect)); } //============================================================================== template template T* SpecializedForAspect::createAspect(Args&&... args) { return _createAspect(type(), std::forward(args)...); } //============================================================================== template template void SpecializedForAspect::removeAspect() { _removeAspect(type()); } //============================================================================== template template std::unique_ptr SpecializedForAspect::releaseAspect() { return _releaseAspect(type()); } //============================================================================== template template constexpr bool SpecializedForAspect::isSpecializedFor() { return _isSpecializedFor(type()); } //============================================================================== template template bool SpecializedForAspect::_has(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS return Composite::has(); } //============================================================================== template bool SpecializedForAspect::_has(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS return (mSpecAspectIterator->second.get() != nullptr); } //============================================================================== template template T* SpecializedForAspect::_get(type) { return Composite::get(); } //============================================================================== template SpecAspect* SpecializedForAspect::_get(type) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS return static_cast(mSpecAspectIterator->second.get()); } //============================================================================== template template const T* SpecializedForAspect::_get(type) const { return Composite::get(); } //============================================================================== template const SpecAspect* SpecializedForAspect::_get(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS return static_cast(mSpecAspectIterator->second.get()); } //============================================================================== template template void SpecializedForAspect::_set(type, const T* aspect) { Composite::set(aspect); } //============================================================================== template void SpecializedForAspect::_set( type, const SpecAspect* aspect) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS if (aspect) { mSpecAspectIterator->second = aspect->cloneAspect(); addToComposite(mSpecAspectIterator->second.get()); } else { mSpecAspectIterator->second = nullptr; } } //============================================================================== template template void SpecializedForAspect::_set( type, std::unique_ptr&& aspect) { Composite::set(std::move(aspect)); } //============================================================================== template void SpecializedForAspect::_set( type, std::unique_ptr&& aspect) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS mSpecAspectIterator->second = std::move(aspect); addToComposite(mSpecAspectIterator->second.get()); } //============================================================================== template template T* SpecializedForAspect::_createAspect(type, Args&&... args) { return Composite::createAspect(std::forward(args)...); } //============================================================================== template template SpecAspect* SpecializedForAspect::_createAspect( type, Args&&... args) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS SpecAspect* aspect = new SpecAspect(std::forward(args)...); mSpecAspectIterator->second = std::unique_ptr(aspect); addToComposite(aspect); return aspect; } //============================================================================== template template void SpecializedForAspect::_removeAspect(type) { Composite::removeAspect(); } //============================================================================== template void SpecializedForAspect::_removeAspect(type) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS DART_COMMON_CHECK_ILLEGAL_ASPECT_ERASE(erase, SpecAspect, DART_BLANK); removeFromComposite(mSpecAspectIterator->second.get()); mSpecAspectIterator->second = nullptr; } //============================================================================== template template std::unique_ptr SpecializedForAspect::_releaseAspect(type) { return Composite::releaseAspect(); } //============================================================================== template std::unique_ptr SpecializedForAspect::_releaseAspect( type) { #ifdef DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS usedSpecializedAspectAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ASPECT_ACCESS DART_COMMON_CHECK_ILLEGAL_ASPECT_ERASE(release, SpecAspect, nullptr); removeFromComposite(mSpecAspectIterator->second.get()); std::unique_ptr extraction( static_cast(mSpecAspectIterator->second.release())); return extraction; } //============================================================================== template template constexpr bool SpecializedForAspect::_isSpecializedFor(type) { return false; } //============================================================================== template constexpr bool SpecializedForAspect::_isSpecializedFor( type) { return true; } } // namespace common } // namespace dart #endif // DART_COMMON_DETAIL_SPECIALIZEDFORASPECT_HPP_