BLPAPI C++ 3.26.7
Loading...
Searching...
No Matches
blpapi_correlationid.h
Go to the documentation of this file.
1/* Copyright 2012. Bloomberg Finance L.P.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions: The above
9 * copyright notice and this permission notice shall be included in all copies
10 * or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
37
38#ifndef INCLUDED_BLPAPI_CORRELATIONID
39#define INCLUDED_BLPAPI_CORRELATIONID
40
69
70#include <blpapi_call.h>
71#include <blpapi_defs.h>
72#include <blpapi_exception.h>
73#include <blpapi_types.h>
74
75#include <stddef.h>
76
77#ifdef __cplusplus
78extern "C" {
79#endif
80
84
86
95struct blpapi_ManagedPtr_t_;
96typedef struct blpapi_ManagedPtr_t_
97 blpapi_ManagedPtr_t;
98
115typedef int (*blpapi_ManagedPtr_ManagerFunction_t)(
116 blpapi_ManagedPtr_t *managedPtr,
117 const blpapi_ManagedPtr_t *srcPtr,
118 int operation);
119
128typedef union {
129 int intValue;
130 void *ptr;
131} blpapi_ManagedPtr_t_data_;
132
140struct blpapi_ManagedPtr_t_ {
141 void *pointer;
142 blpapi_ManagedPtr_t_data_
143 userData[4];
144 blpapi_ManagedPtr_ManagerFunction_t
145 manager;
146};
147
156typedef struct blpapi_CorrelationId_t_ {
157 unsigned int size : 8;
158 unsigned int valueType
159 : 4;
160 unsigned int classId
161 : 16;
162 unsigned int internalClassId : 4;
163
164 union {
165 blpapi_UInt64_t intValue;
166 blpapi_ManagedPtr_t
167 ptrValue;
168 } value;
169} blpapi_CorrelationId_t;
170
187BLPAPI_EXPORT
188int blpapi_CorrelationId_managedPtrAddRef(
189 int *numRef, blpapi_CorrelationId_t *cid);
190
208BLPAPI_EXPORT
209int blpapi_CorrelationId_managedPtrRelease(
210 int *numRef, blpapi_CorrelationId_t *cid);
211
223BLPAPI_EXPORT
224int blpapi_CorrelationId_hash(size_t *hash, const blpapi_CorrelationId_t *cid);
226
228
229#ifdef __cplusplus
230}
231
232#include <cstring>
233#include <ostream>
234#include <utility>
235
236namespace BloombergLP {
237namespace blpapi {
244
245// ===================
246// class CorrelationId
247// ===================
248
323
324 enum {
325 e_FOREIGN_OBJECT = BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
326 };
327
329 blpapi_CorrelationId_t d_impl;
330
331 void copy(const blpapi_CorrelationId_t& src, bool firstCopy);
332
333 template <typename TYPE>
334 static int managerFunc(blpapi_ManagedPtr_t *managedPtr,
335 const blpapi_ManagedPtr_t *srcPtr,
336 int operation);
338
339 template <typename TYPE> static void assertSmartPtrFits();
340
341 public:
342 // Possible return values for valueType() method.
343
345 UNSET_VALUE = BLPAPI_CORRELATION_TYPE_UNSET,
348 INT_VALUE = BLPAPI_CORRELATION_TYPE_INT,
351 POINTER_VALUE = BLPAPI_CORRELATION_TYPE_POINTER,
354 AUTOGEN_VALUE = BLPAPI_CORRELATION_TYPE_AUTOGEN
356 };
357
358 // The maximum value allowed for classId
359
360 enum {
361 MAX_CLASS_ID = BLPAPI_CORRELATION_MAX_CLASS_ID
363 };
364
372
374 explicit CorrelationId(const blpapi_CorrelationId_t& correlation);
379
380 CorrelationId(const CorrelationId& original);
385
386 explicit CorrelationId(long long value, int classId = 0);
392
393 explicit CorrelationId(void *value, int classId = 0);
399
400 template <typename TYPE>
401 CorrelationId(const TYPE& smartPtr, void *pointerValue, int classId = 0);
411
417
418 void swap(CorrelationId& other);
423
430
431 ValueType valueType() const;
435
436 unsigned short classId() const;
441
442 void *asPointer() const;
448
449 template <typename TYPE> TYPE asSmartPointer() const;
456
457 long long asInteger() const;
463
465 blpapi_CorrelationId_t& impl();
466 const blpapi_CorrelationId_t& impl() const;
468};
469
472
473// FREE OPERATORS
474inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs);
482
483inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs);
487
488inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs);
498
499namespace util {
500
504
505constexpr const char *to_string(CorrelationId::ValueType valueType);
509
511
512} // close namespace util
513
514//=============================================================================
515// INLINE FUNCTION DEFINITIONS
516//=============================================================================
517
518// -------------------
519// class CorrelationId
520// -------------------
521
523{
524 std::memset(&d_impl, 0, sizeof(d_impl));
525}
526
529 const blpapi_CorrelationId_t& correlationId)
530{
531 copy(correlationId, /* firstCopy = */ true);
532}
534
536{
537 copy(original.d_impl, /* firstCopy = */ false);
538}
539
540inline CorrelationId::CorrelationId(long long intValue, int newClassId)
541{
542 std::memset(&d_impl, 0, sizeof(d_impl));
543
544 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
545 d_impl.valueType = INT_VALUE;
546 d_impl.value.intValue = static_cast<blpapi_UInt64_t>(intValue);
547 d_impl.classId = static_cast<unsigned>(newClassId);
548}
549
550inline CorrelationId::CorrelationId(void *ptrValue, int newClassId)
551{
552 std::memset(&d_impl, 0, sizeof(d_impl));
553
554 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
555 d_impl.valueType = POINTER_VALUE;
556 d_impl.value.ptrValue.pointer = ptrValue;
557 d_impl.classId = static_cast<unsigned>(newClassId);
558}
559
560template <typename TYPE>
562 const TYPE& smartPtr, void *ptrValue, int newClassId)
563{
564 // If you get a compiler error here, the specified smart pointer does not
565 // fit in the CorrelationId and cannot be used at this time.
566
567 assertSmartPtrFits<TYPE>();
568
569 std::memset(&d_impl, 0, sizeof(d_impl));
570
571 d_impl.size = sizeof(d_impl);
572 d_impl.valueType = POINTER_VALUE;
573 d_impl.classId = newClassId;
574
575 d_impl.value.ptrValue.pointer = ptrValue;
576 d_impl.value.ptrValue.manager = &CorrelationId::managerFunc<TYPE>;
577
578 void *arena = (void *)d_impl.value.ptrValue.userData;
579 new (arena) TYPE(smartPtr);
580}
581
583{
584 if (POINTER_VALUE == valueType()) {
585 blpapi_ManagedPtr_ManagerFunction_t& manager
586 = d_impl.value.ptrValue.manager;
587 if (manager) {
588 int numRef = 0;
589 if (d_impl.internalClassId == e_FOREIGN_OBJECT
590 && BLPAPI_CALL_AVAILABLE(
591 blpapi_CorrelationId_managedPtrRelease)
592 && BLPAPI_CALL_UNCHECKED(
593 blpapi_CorrelationId_managedPtrRelease)(
594 &numRef, &d_impl)
595 == 0
596 && numRef > 0) {
597 return;
598 }
599 manager(&d_impl.value.ptrValue, 0, BLPAPI_MANAGEDPTR_DESTROY);
600 }
601 }
602}
603
605{
606 using std::swap;
607
608 swap(other.d_impl, d_impl);
609}
610
612{
613 CorrelationId tmp(rhs);
614 tmp.swap(*this);
615 return *this;
616}
617
619inline blpapi_CorrelationId_t& CorrelationId::impl() { return d_impl; }
621
623{
624 return (ValueType)d_impl.valueType;
625}
626
627inline unsigned short CorrelationId::classId() const { return d_impl.classId; }
628
629inline void *CorrelationId::asPointer() const
630{
631 return d_impl.value.ptrValue.pointer;
632}
633
634template <typename TYPE> inline TYPE CorrelationId::asSmartPointer() const
635{
636 typedef int (*ManagerFuncPtr)(
637 blpapi_ManagedPtr_t *, const blpapi_ManagedPtr_t *, int);
638
639 ManagerFuncPtr managerFnPtr
640 = static_cast<ManagerFuncPtr>(&(CorrelationId::managerFunc<TYPE>));
641 if (d_impl.valueType != POINTER_VALUE
642 || (d_impl.value.ptrValue.manager != managerFnPtr)) {
643 return TYPE();
644 }
645 return *(TYPE *)d_impl.value.ptrValue.userData;
646}
647
648inline long long CorrelationId::asInteger() const
649{
650 return static_cast<long long>(d_impl.value.intValue);
651}
652
654inline const blpapi_CorrelationId_t& CorrelationId::impl() const
655{
656 return d_impl;
657}
659
661inline void CorrelationId::copy(
662 const blpapi_CorrelationId_t& src, bool firstCopy)
663{
664 d_impl = src;
665
666 if (POINTER_VALUE == valueType()) {
667 blpapi_ManagedPtr_ManagerFunction_t& manager
668 = d_impl.value.ptrValue.manager;
669 if (manager) {
670 if (d_impl.internalClassId == e_FOREIGN_OBJECT) {
671 if (firstCopy) {
672 // This CorrelationId is created from a C-handle, not from
673 // another C++ CorrelationId. But this C-handle can contain
674 // a pointer to a reference counter previously created in
675 // C++ layer. It is unsafe to reuse as it might be a
676 // dangling pointer by this time. Reset userData. This
677 // allows to create a new reference counter for new C++
678 // copies of this CorrelationId.
679 std::memset(&d_impl.value.ptrValue.userData,
680 0,
681 sizeof(d_impl.value.ptrValue.userData));
682 }
683 int numRef = 0;
685 BLPAPI_CALL(blpapi_CorrelationId_managedPtrAddRef)(
686 &numRef, &d_impl));
687 if (numRef > 1) {
688 return;
689 }
690 }
691 manager(&d_impl.value.ptrValue,
692 &src.value.ptrValue,
693 BLPAPI_MANAGEDPTR_COPY);
694 }
695 }
696}
698
700template <typename TYPE>
701inline int CorrelationId::managerFunc(blpapi_ManagedPtr_t *managedPtr,
702 const blpapi_ManagedPtr_t *srcPtr,
703 int operation)
704{
705 if (operation == BLPAPI_MANAGEDPTR_COPY) {
706 managedPtr->pointer = srcPtr->pointer;
707 managedPtr->manager = srcPtr->manager;
708
709 void *arena = managedPtr->userData;
710 new (arena) TYPE(*((TYPE *)&srcPtr->userData[0]));
711 } else if (operation == BLPAPI_MANAGEDPTR_DESTROY) {
712 TYPE *managedPtr_p = (TYPE *)&managedPtr->userData[0];
713 managedPtr_p->~TYPE();
714 } else if (operation == BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION) {
715 static int uniquePerTemplateInstantiation;
716
717 const int *address = &uniquePerTemplateInstantiation;
718 int rc = 0;
719 std::memcpy(&rc, &address, std::min(sizeof address, sizeof rc));
720 return rc;
721 // Instantiations of this function template, 'managerFunc<TYPE>',
722 // will never be called with 'operation' equal to
723 // 'BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION': this branch will never
724 // be executed.
725 //
726 // The observable use of the address of a local static variable
727 // forces '&managerFunc<T1> != &managerFunc<T2>' for types
728 // 'T1 != T2' even in the presence of Visual C++'s "identical
729 // COMDAT folding" optimization.
730 }
731
732 return 0;
733}
735
736template <typename TYPE> inline void CorrelationId::assertSmartPtrFits()
737{
738 if (false) {
739 // If you get a compiler error here, the specified smart pointer does
740 // not fit in the CorrelationId and cannot be used at this time.
741
742 char errorIfSmartPtrDoesNotFit[sizeof(TYPE) <= (sizeof(void *) * 4)
743 ? 1
744 : -1];
745 (void)errorIfSmartPtrDoesNotFit;
746 }
747}
748
749inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs)
750{
751 if (lhs.valueType() != rhs.valueType()) {
752 return false;
753 }
754 if (lhs.classId() != rhs.classId()) {
755 return false;
756 }
757 if (lhs.impl().internalClassId != rhs.impl().internalClassId) {
758 return false;
759 }
760
762 if (lhs.asPointer() != rhs.asPointer()) {
763 return false;
764 }
765 } else if (lhs.asInteger() != rhs.asInteger()) {
766 return false;
767 }
768
769 return true;
770}
771
772inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs)
773{
774 return !(lhs == rhs);
775}
776
777inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs)
778{
780 && lhs.impl().internalClassId
781 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
783 && rhs.impl().internalClassId
784 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT) {
785 return lhs.classId() == rhs.classId()
786 ? lhs.asPointer() < rhs.asPointer()
787 : lhs.classId() < rhs.classId();
788 }
789 return std::memcmp(&lhs.impl(), &rhs.impl(), sizeof(rhs.impl())) < 0;
790}
791
792inline std::ostream& operator<<(
793 std::ostream& os, const CorrelationId& correlator)
794{
795 const char *valueType = 0;
796 switch (correlator.valueType()) {
798 valueType = "UNSET";
799 break;
801 valueType = "INT";
802 break;
804 valueType = "POINTER";
805 break;
807 valueType = "AUTOGEN";
808 break;
809 default:
810 valueType = "UNKNOWN";
811 }
812
813 os << "[ valueType=" << valueType << " classId=" << correlator.classId()
814 << " internalClassId=" << correlator.impl().internalClassId
815 << " value=";
816
817 if (correlator.valueType() == CorrelationId::POINTER_VALUE) {
818 os << correlator.asPointer();
819 } else {
820 os << correlator.asInteger();
821 }
822 os << " ]";
823
824 return os;
825}
826
827// --------------
828// namespace util
829// --------------
830constexpr const char *util::to_string(CorrelationId::ValueType valueType)
831{
832 switch (valueType) {
834 return "UNSET_VALUE";
836 return "INT_VALUE";
838 return "POINTER_VALUE";
840 return "AUTOGEN_VALUE";
841 }
842 // Silence warnings on some compilers
843 return "UNDEFINED";
844}
845
846} // close namespace blpapi
847} // close namespace BloombergLP
848
849#endif // #ifdef __cplusplus
850#endif // #ifndef INCLUDED_BLPAPI_CORRELATIONID
Provide functions for dispatchtbl.
Common definitions used by the library.
Defines Exceptions that can be thrown by the blpapi library.
Provide BLPAPI types.
Definition blpapi_correlationid.h:322
@ MAX_CLASS_ID
Definition blpapi_correlationid.h:361
void swap(CorrelationId &other)
Definition blpapi_correlationid.h:604
unsigned short classId() const
Definition blpapi_correlationid.h:627
ValueType valueType() const
Definition blpapi_correlationid.h:622
void * asPointer() const
Definition blpapi_correlationid.h:629
TYPE asSmartPointer() const
Definition blpapi_correlationid.h:634
~CorrelationId()
Definition blpapi_correlationid.h:582
CorrelationId()
Definition blpapi_correlationid.h:522
long long asInteger() const
Definition blpapi_correlationid.h:648
ValueType
Definition blpapi_correlationid.h:344
@ AUTOGEN_VALUE
The CorrelationId was created internally by API.
Definition blpapi_correlationid.h:354
@ UNSET_VALUE
Definition blpapi_correlationid.h:345
@ INT_VALUE
Definition blpapi_correlationid.h:348
@ POINTER_VALUE
Definition blpapi_correlationid.h:351
CorrelationId & operator=(const CorrelationId &rhs)
Definition blpapi_correlationid.h:611
static void throwOnError(int errorCode)
Definition blpapi_exception.h:556
constexpr const char * to_string(CorrelationId::ValueType valueType)
Definition blpapi_correlationid.h:830
Definition blpapi_correlationid.h:499
Definition blpapi_abstractsession.h:448
bool operator==(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:749
std::ostream & operator<<(std::ostream &os, const CorrelationId &correlator)
Definition blpapi_correlationid.h:792
bool operator!=(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:772
bool operator<(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:777
Definition blpapi_abstractsession.h:447